Module xboto.dependencies

A few classes/resources that let you use a lazily created boto resource/client, in a thread-safe manner:

Normally, you would just get it via an attribute name, in this version you

>>> boto_clients.ssm.get_paginator()

Or you can import it like so:

>>> from xboto.client import ssm
>>> ssm.get_paginator()

Same with resources:

>>> boto_resources.dynamodb.Table("some-table")

Or

>>> from xboto.client import dynamodb
>>> dynamodb.Table("some-table")

Global variables

var boto_clients

You can import this and then ask it for clients via attributes.

Example:

>>> from xboto import boto_clients
>>>
>>> # Get the ssm client (ask for it each time), then get it's paginator.
>>> boto_clients.ssm.get_paginator(...)

You can also directly import a client like so:

>>> from xboto.client import ssm
>>>
>>> # You can just use it directly anytime you need too:
>>> ssm.get_paginator()

Or import top-level object only:

import xboto

>>> # You can just use any client you want:
>>> xboto.client.ssm.get_paginator()
var boto_resources

You can import this and then ask it for clients via attributes.

Example:

>>> from xboto import boto_resources FINISH HERE!!!!! ****
>>>
>>> # Get the ssm client (ask for it each time), then get it's paginator.
>>> boto_resources.dynamodb.create_table()

You can also directly import a client like so:

>>> from xboto.resource import dynamodb
>>>
>>> # You can just use it directly anytime you need too:
>>> dynamodb.create_table()

Or import top-level object only:

import xboto

>>> # You can just use any client you want:
>>> xboto.resource.dynamodb.create_table()
var boto_session

You can use this as the current 'boto' session object. _Loader subclasses use this right now (see below).

Classes

class BotoClient (region_name=None,
api_version=None,
use_ssl=None,
verify=None,
endpoint_url=None,
aws_access_key_id=None,
aws_secret_access_key=None,
aws_session_token=None,
config=None,
**boto_kwargs)
Expand source code
class BotoClient(_BaseBotoClientOrResource, boto_kind='client'):
    @property
    def boto_client(self):
        return self.get()

    @classmethod
    def get_dependency_cls(cls, boto_name: str) -> 'Type[BotoClient]':
        return cls._get_dependency_cls(boto_name)

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

You can specify any of the boto client/resource args, the known ones have been specififed and documented out.

If there are ones in the future that are new or we don't know about, you can still specify them, they will be passed to us in boto_kwargs, which will be used as addtional kwargs when creating new boto client/resource.

Args

region_name
The name of the region associated with the client. A client is associated with a single region.
api_version
The API version to use. By default, botocore will use the latest API version when creating a client.You only need to specify this parameter if you want to use a previous API version of the client.
use_ssl
Whether or not to use SSL. By default, SSL is used. Note that not all services support non-ssl connections.
verify

Whether or not to verify SSL certificates. By default SSL certificates are verified. You can provide the following values:

  • False - do not validate SSL certificates. SSL will still be used (unless use_ssl is False), but SSL certificates will not be verified.
  • path/to/cert/bundle.pem - A filename of the CA cert bundle to uses. You can specify this argument if you want to use a different CA cert bundle than the one used by botocore.
endpoint_url
The complete URL to use for the constructed client. Normally, botocore will automatically construct the appropriate URL to use when communicating with a service. You can specify a complete URL (including the "http/https" scheme) to override this behavior. If this value is provided, then use_ssl is ignored.
aws_access_key_id
The access key to use when creating the client. This is entirely optional, and if not provided, the credentials configured for the session will automatically be used. You only need to provide this argument if you want to override the credentials used for this specific client.
aws_secret_access_key
The secret key to use when creating the client. Same semantics as aws_access_key_id above.
aws_session_token
The session token to use when creating the client. Same semantics as aws_access_key_id above.
config
Advanced client configuration options. If region_name is specified in the client config, its value will take precedence over environment variables and configuration values, but not over a region_name value passed explicitly to the method. If user_agent_extra is specified in the client config, it overrides the default user_agent_extra provided by the resource API. See botocore config documentation for more details.

**boto_kwargs:

Ancestors

  • xboto.dependencies._BaseBotoClientOrResource
  • Dependency

Subclasses

  • xboto.dependencies.AccessanalyzerClient
  • xboto.dependencies.AccountClient
  • xboto.dependencies.Acm-pcaClient
  • xboto.dependencies.AcmClient
  • xboto.dependencies.AlexaforbusinessClient
  • xboto.dependencies.AmpClient
  • xboto.dependencies.AmplifyClient
  • xboto.dependencies.AmplifybackendClient
  • xboto.dependencies.AmplifyuibuilderClient
  • xboto.dependencies.ApigatewayClient
  • xboto.dependencies.ApigatewaymanagementapiClient
  • xboto.dependencies.Apigatewayv2Client
  • xboto.dependencies.AppconfigClient
  • xboto.dependencies.AppconfigdataClient
  • xboto.dependencies.AppflowClient
  • xboto.dependencies.AppintegrationsClient
  • xboto.dependencies.Application-autoscalingClient
  • xboto.dependencies.Application-insightsClient
  • xboto.dependencies.ApplicationcostprofilerClient
  • xboto.dependencies.AppmeshClient
  • xboto.dependencies.ApprunnerClient
  • xboto.dependencies.AppstreamClient
  • xboto.dependencies.AppsyncClient
  • xboto.dependencies.Arc-zonal-shiftClient
  • xboto.dependencies.AthenaClient
  • xboto.dependencies.AuditmanagerClient
  • xboto.dependencies.Autoscaling-plansClient
  • xboto.dependencies.AutoscalingClient
  • xboto.dependencies.Backup-gatewayClient
  • xboto.dependencies.BackupClient
  • xboto.dependencies.BackupstorageClient
  • xboto.dependencies.BatchClient
  • xboto.dependencies.BillingconductorClient
  • xboto.dependencies.BraketClient
  • xboto.dependencies.BudgetsClient
  • xboto.dependencies.CeClient
  • xboto.dependencies.Chime-sdk-identityClient
  • xboto.dependencies.Chime-sdk-media-pipelinesClient
  • xboto.dependencies.Chime-sdk-meetingsClient
  • xboto.dependencies.Chime-sdk-messagingClient
  • xboto.dependencies.Chime-sdk-voiceClient
  • xboto.dependencies.ChimeClient
  • xboto.dependencies.CleanroomsClient
  • xboto.dependencies.Cloud9Client
  • xboto.dependencies.CloudcontrolClient
  • xboto.dependencies.ClouddirectoryClient
  • xboto.dependencies.CloudformationClient
  • xboto.dependencies.CloudfrontClient
  • xboto.dependencies.CloudhsmClient
  • xboto.dependencies.Cloudhsmv2Client
  • xboto.dependencies.CloudsearchClient
  • xboto.dependencies.CloudsearchdomainClient
  • xboto.dependencies.Cloudtrail-dataClient
  • xboto.dependencies.CloudtrailClient
  • xboto.dependencies.CloudwatchClient
  • xboto.dependencies.CodeartifactClient
  • xboto.dependencies.CodebuildClient
  • xboto.dependencies.CodecatalystClient
  • xboto.dependencies.CodecommitClient
  • xboto.dependencies.CodedeployClient
  • xboto.dependencies.Codeguru-reviewerClient
  • xboto.dependencies.CodeguruprofilerClient
  • xboto.dependencies.CodepipelineClient
  • xboto.dependencies.Codestar-connectionsClient
  • xboto.dependencies.Codestar-notificationsClient
  • xboto.dependencies.CodestarClient
  • xboto.dependencies.Cognito-identityClient
  • xboto.dependencies.Cognito-idpClient
  • xboto.dependencies.Cognito-syncClient
  • xboto.dependencies.ComprehendClient
  • xboto.dependencies.ComprehendmedicalClient
  • xboto.dependencies.Compute-optimizerClient
  • xboto.dependencies.ConfigClient
  • xboto.dependencies.Connect-contact-lensClient
  • xboto.dependencies.ConnectClient
  • xboto.dependencies.ConnectcampaignsClient
  • xboto.dependencies.ConnectcasesClient
  • xboto.dependencies.ConnectparticipantClient
  • xboto.dependencies.ControltowerClient
  • xboto.dependencies.CurClient
  • xboto.dependencies.Customer-profilesClient
  • xboto.dependencies.DatabrewClient
  • xboto.dependencies.DataexchangeClient
  • xboto.dependencies.DatapipelineClient
  • xboto.dependencies.DatasyncClient
  • xboto.dependencies.DaxClient
  • xboto.dependencies.DetectiveClient
  • xboto.dependencies.DevicefarmClient
  • xboto.dependencies.Devops-guruClient
  • xboto.dependencies.DirectconnectClient
  • xboto.dependencies.DiscoveryClient
  • xboto.dependencies.DlmClient
  • xboto.dependencies.DmsClient
  • xboto.dependencies.Docdb-elasticClient
  • xboto.dependencies.DocdbClient
  • xboto.dependencies.DrsClient
  • xboto.dependencies.DsClient
  • xboto.dependencies.DynamodbClient
  • xboto.dependencies.DynamodbstreamsClient
  • xboto.dependencies.EbsClient
  • xboto.dependencies.Ec2-instance-connectClient
  • xboto.dependencies.Ec2Client
  • xboto.dependencies.Ecr-publicClient
  • xboto.dependencies.EcrClient
  • xboto.dependencies.EcsClient
  • xboto.dependencies.EfsClient
  • xboto.dependencies.EksClient
  • xboto.dependencies.Elastic-inferenceClient
  • xboto.dependencies.ElasticacheClient
  • xboto.dependencies.ElasticbeanstalkClient
  • xboto.dependencies.ElastictranscoderClient
  • xboto.dependencies.ElbClient
  • xboto.dependencies.Elbv2Client
  • xboto.dependencies.Emr-containersClient
  • xboto.dependencies.Emr-serverlessClient
  • xboto.dependencies.EmrClient
  • xboto.dependencies.EsClient
  • xboto.dependencies.EventsClient
  • xboto.dependencies.EvidentlyClient
  • xboto.dependencies.Finspace-dataClient
  • xboto.dependencies.FinspaceClient
  • xboto.dependencies.FirehoseClient
  • xboto.dependencies.FisClient
  • xboto.dependencies.FmsClient
  • xboto.dependencies.ForecastClient
  • xboto.dependencies.ForecastqueryClient
  • xboto.dependencies.FrauddetectorClient
  • xboto.dependencies.FsxClient
  • xboto.dependencies.GameliftClient
  • xboto.dependencies.GamesparksClient
  • xboto.dependencies.GlacierClient
  • xboto.dependencies.GlobalacceleratorClient
  • xboto.dependencies.GlueClient
  • xboto.dependencies.GrafanaClient
  • xboto.dependencies.GreengrassClient
  • xboto.dependencies.Greengrassv2Client
  • xboto.dependencies.GroundstationClient
  • xboto.dependencies.GuarddutyClient
  • xboto.dependencies.HealthClient
  • xboto.dependencies.HealthlakeClient
  • xboto.dependencies.HoneycodeClient
  • xboto.dependencies.IamClient
  • xboto.dependencies.IdentitystoreClient
  • xboto.dependencies.ImagebuilderClient
  • xboto.dependencies.ImportexportClient
  • xboto.dependencies.Inspector2Client
  • xboto.dependencies.InspectorClient
  • xboto.dependencies.Iot-dataClient
  • xboto.dependencies.Iot-jobs-dataClient
  • xboto.dependencies.Iot-roborunnerClient
  • xboto.dependencies.Iot1click-devicesClient
  • xboto.dependencies.Iot1click-projectsClient
  • xboto.dependencies.IotClient
  • xboto.dependencies.IotanalyticsClient
  • xboto.dependencies.IotdeviceadvisorClient
  • xboto.dependencies.Iotevents-dataClient
  • xboto.dependencies.IoteventsClient
  • xboto.dependencies.IotfleethubClient
  • xboto.dependencies.IotfleetwiseClient
  • xboto.dependencies.IotsecuretunnelingClient
  • xboto.dependencies.IotsitewiseClient
  • xboto.dependencies.IotthingsgraphClient
  • xboto.dependencies.IottwinmakerClient
  • xboto.dependencies.IotwirelessClient
  • xboto.dependencies.IvsClient
  • xboto.dependencies.IvschatClient
  • xboto.dependencies.KafkaClient
  • xboto.dependencies.KafkaconnectClient
  • xboto.dependencies.Kendra-rankingClient
  • xboto.dependencies.KendraClient
  • xboto.dependencies.KeyspacesClient
  • xboto.dependencies.Kinesis-video-archived-mediaClient
  • xboto.dependencies.Kinesis-video-mediaClient
  • xboto.dependencies.Kinesis-video-signalingClient
  • xboto.dependencies.Kinesis-video-webrtc-storageClient
  • xboto.dependencies.KinesisClient
  • xboto.dependencies.KinesisanalyticsClient
  • xboto.dependencies.Kinesisanalyticsv2Client
  • xboto.dependencies.KinesisvideoClient
  • xboto.dependencies.KmsClient
  • xboto.dependencies.LakeformationClient
  • xboto.dependencies.LambdaClient
  • xboto.dependencies.Lex-modelsClient
  • xboto.dependencies.Lex-runtimeClient
  • xboto.dependencies.Lexv2-modelsClient
  • xboto.dependencies.Lexv2-runtimeClient
  • xboto.dependencies.License-manager-linux-subscriptionsClient
  • xboto.dependencies.License-manager-user-subscriptionsClient
  • xboto.dependencies.License-managerClient
  • xboto.dependencies.LightsailClient
  • xboto.dependencies.LocationClient
  • xboto.dependencies.LogsClient
  • xboto.dependencies.LookoutequipmentClient
  • xboto.dependencies.LookoutmetricsClient
  • xboto.dependencies.LookoutvisionClient
  • xboto.dependencies.M2Client
  • xboto.dependencies.MachinelearningClient
  • xboto.dependencies.Macie2Client
  • xboto.dependencies.MacieClient
  • xboto.dependencies.ManagedblockchainClient
  • xboto.dependencies.Marketplace-catalogClient
  • xboto.dependencies.Marketplace-entitlementClient
  • xboto.dependencies.MarketplacecommerceanalyticsClient
  • xboto.dependencies.MediaconnectClient
  • xboto.dependencies.MediaconvertClient
  • xboto.dependencies.MedialiveClient
  • xboto.dependencies.Mediapackage-vodClient
  • xboto.dependencies.MediapackageClient
  • xboto.dependencies.Mediastore-dataClient
  • xboto.dependencies.MediastoreClient
  • xboto.dependencies.MediatailorClient
  • xboto.dependencies.MemorydbClient
  • xboto.dependencies.MeteringmarketplaceClient
  • xboto.dependencies.MghClient
  • xboto.dependencies.MgnClient
  • xboto.dependencies.Migration-hub-refactor-spacesClient
  • xboto.dependencies.Migrationhub-configClient
  • xboto.dependencies.MigrationhuborchestratorClient
  • xboto.dependencies.MigrationhubstrategyClient
  • xboto.dependencies.MobileClient
  • xboto.dependencies.MqClient
  • xboto.dependencies.MturkClient
  • xboto.dependencies.MwaaClient
  • xboto.dependencies.NeptuneClient
  • xboto.dependencies.Network-firewallClient
  • xboto.dependencies.NetworkmanagerClient
  • xboto.dependencies.NimbleClient
  • xboto.dependencies.OamClient
  • xboto.dependencies.OmicsClient
  • xboto.dependencies.OpensearchClient
  • xboto.dependencies.OpensearchserverlessClient
  • xboto.dependencies.OpsworksClient
  • xboto.dependencies.OpsworkscmClient
  • xboto.dependencies.OrganizationsClient
  • xboto.dependencies.OutpostsClient
  • xboto.dependencies.PanoramaClient
  • xboto.dependencies.Personalize-eventsClient
  • xboto.dependencies.Personalize-runtimeClient
  • xboto.dependencies.PersonalizeClient
  • xboto.dependencies.PiClient
  • xboto.dependencies.Pinpoint-emailClient
  • xboto.dependencies.Pinpoint-sms-voice-v2Client
  • xboto.dependencies.Pinpoint-sms-voiceClient
  • xboto.dependencies.PinpointClient
  • xboto.dependencies.PipesClient
  • xboto.dependencies.PollyClient
  • xboto.dependencies.PricingClient
  • xboto.dependencies.PrivatenetworksClient
  • xboto.dependencies.ProtonClient
  • xboto.dependencies.Qldb-sessionClient
  • xboto.dependencies.QldbClient
  • xboto.dependencies.QuicksightClient
  • xboto.dependencies.RamClient
  • xboto.dependencies.RbinClient
  • xboto.dependencies.Rds-dataClient
  • xboto.dependencies.RdsClient
  • xboto.dependencies.Redshift-dataClient
  • xboto.dependencies.Redshift-serverlessClient
  • xboto.dependencies.RedshiftClient
  • xboto.dependencies.RekognitionClient
  • xboto.dependencies.ResiliencehubClient
  • xboto.dependencies.Resource-explorer-2Client
  • xboto.dependencies.Resource-groupsClient
  • xboto.dependencies.ResourcegroupstaggingapiClient
  • xboto.dependencies.RobomakerClient
  • xboto.dependencies.RolesanywhereClient
  • xboto.dependencies.Route53-recovery-clusterClient
  • xboto.dependencies.Route53-recovery-control-configClient
  • xboto.dependencies.Route53-recovery-readinessClient
  • xboto.dependencies.Route53Client
  • xboto.dependencies.Route53domainsClient
  • xboto.dependencies.Route53resolverClient
  • xboto.dependencies.RumClient
  • xboto.dependencies.S3Client
  • xboto.dependencies.S3controlClient
  • xboto.dependencies.S3outpostsClient
  • xboto.dependencies.Sagemaker-a2i-runtimeClient
  • xboto.dependencies.Sagemaker-edgeClient
  • xboto.dependencies.Sagemaker-featurestore-runtimeClient
  • xboto.dependencies.Sagemaker-geospatialClient
  • xboto.dependencies.Sagemaker-metricsClient
  • xboto.dependencies.Sagemaker-runtimeClient
  • xboto.dependencies.SagemakerClient
  • xboto.dependencies.SavingsplansClient
  • xboto.dependencies.SchedulerClient
  • xboto.dependencies.SchemasClient
  • xboto.dependencies.SdbClient
  • xboto.dependencies.SecretsmanagerClient
  • xboto.dependencies.SecurityhubClient
  • xboto.dependencies.SecuritylakeClient
  • xboto.dependencies.ServerlessrepoClient
  • xboto.dependencies.Service-quotasClient
  • xboto.dependencies.Servicecatalog-appregistryClient
  • xboto.dependencies.ServicecatalogClient
  • xboto.dependencies.ServicediscoveryClient
  • xboto.dependencies.SesClient
  • xboto.dependencies.Sesv2Client
  • xboto.dependencies.ShieldClient
  • xboto.dependencies.SignerClient
  • xboto.dependencies.SimspaceweaverClient
  • xboto.dependencies.Sms-voiceClient
  • xboto.dependencies.SmsClient
  • xboto.dependencies.Snow-device-managementClient
  • xboto.dependencies.SnowballClient
  • xboto.dependencies.SnsClient
  • xboto.dependencies.SqsClient
  • xboto.dependencies.Ssm-contactsClient
  • xboto.dependencies.Ssm-incidentsClient
  • xboto.dependencies.Ssm-sapClient
  • xboto.dependencies.SsmClient
  • xboto.dependencies.Sso-adminClient
  • xboto.dependencies.Sso-oidcClient
  • xboto.dependencies.SsoClient
  • xboto.dependencies.StepfunctionsClient
  • xboto.dependencies.StoragegatewayClient
  • xboto.dependencies.StsClient
  • xboto.dependencies.Support-appClient
  • xboto.dependencies.SupportClient
  • xboto.dependencies.SwfClient
  • xboto.dependencies.SyntheticsClient
  • xboto.dependencies.TextractClient
  • xboto.dependencies.Timestream-queryClient
  • xboto.dependencies.Timestream-writeClient
  • xboto.dependencies.TranscribeClient
  • xboto.dependencies.TransferClient
  • xboto.dependencies.TranslateClient
  • xboto.dependencies.Voice-idClient
  • xboto.dependencies.Waf-regionalClient
  • xboto.dependencies.WafClient
  • xboto.dependencies.Wafv2Client
  • xboto.dependencies.WellarchitectedClient
  • xboto.dependencies.WisdomClient
  • xboto.dependencies.WorkdocsClient
  • xboto.dependencies.WorklinkClient
  • xboto.dependencies.WorkmailClient
  • xboto.dependencies.WorkmailmessageflowClient
  • xboto.dependencies.Workspaces-webClient
  • xboto.dependencies.WorkspacesClient
  • xboto.dependencies.XrayClient

Static methods

def __init_subclass__(thread_sharable: bool | DefaultType = Default,
remove_between_unittests: bool | DefaultType = Default,
attributes_to_skip_while_copying: Iterable[str] | None = Default,
**kwargs)

Inherited from: Dependency.__init_subclass__

Args

remove_between_unittests
If False (default): Dependency will be removed from global context before/after as each individual …
def get_dependency_cls(boto_name: str) ‑> Type[BotoClient]
def grab() ‑> ~T

Inherited from: Dependency.grab

Gets a potentially shared dependency from the current udpend.context.XContext

def proxy() ‑> ~R

Inherited from: Dependency.proxy

Returns a proxy-object, that when and attribute is asked for, it will proxy it to the current object of cls

def proxy_attribute(attribute_name: str) ‑> Any

Inherited from: Dependency.proxy_attribute

Returns a proxy-object, that when and attribute is asked for, it will proxy it to the current attribute value on the current object of cls

Instance variables

prop boto_client
Expand source code
@property
def boto_client(self):
    return self.get()
var obj : ClassVar[Self]

Inherited from: Dependency.obj

class property/attribute that will return the current dependency for the subclass it's asked on by calling Dependency.grab, passing no extra …

Methods

def __call__(self, func)

Inherited from: Dependency.__call__

This makes Resource subclasses have an ability to be used as function decorators by default unless this method is overriden to provide some other …

def __copy__(self)

Inherited from: Dependency.__copy__

Basic shallow copy protection (I am wondering if I should just remove this default copy code) …

class BotoClients
Expand source code
class BotoClients(_Loader, boto_dependency_class=BotoClient):
    """
    When you get an attribute off of me, I'll attempt to ask the boto3 library to allocate
    a client of the same type, and then store itself, so I return the same client again
    in the future.

    Right now, we will lazily allocate a boto3 client per-thread, and we will use the
    per-thread shared boto3 session resource to do it (ie: `_BotoSession.session`).

    You can also easily import and use the `boto_clients` proxy object
    (defined at top module-level).

    You can use `boto_clients` exactly the same as using `BotoClients.grab()`,
    making it more convenient to use since you can directly import `boto_clients`.

    >>> from xboto import boto_clients
    >>> # Showing here how you could use it:
    >>> boto_clients.ssm.get_paginator(...)

    If you have an aws client that uses a `-` for it's name, you can use an `_` (underscore)
    instead.
    All underscores are changed to a `-` when looking up the aws client.
    You can also directly use the `xboto.dependencies.BotoClients.load` method, and use a `-`
    there.
    """

    def _lookup(self, module):
        return BotoClient.get_dependency_cls(module).grab().boto_client

    # These annotations are only for IDE-type-completion;
    # any client boto supports will work regardless (even if not listed below).
    #
    # These are the xyn-resource `Resource` types/classes; ie: BotoClient subclasses
    # (start with upper-case letter)
    AccessAnalyzer: Type[BotoClient]
    Account: Type[BotoClient]
    Acm: Type[BotoClient]
    Acm_Pca: Type[BotoClient]
    AlexaForBusiness: Type[BotoClient]
    Amp: Type[BotoClient]
    Amplify: Type[BotoClient]
    AmplifyBackend: Type[BotoClient]
    AmplifyUiBuilder: Type[BotoClient]
    ApiGateway: Type[BotoClient]
    ApiGatewayManagementApi: Type[BotoClient]
    ApiGatewayV2: Type[BotoClient]
    AppConfig: Type[BotoClient]
    AppConfigData: Type[BotoClient]
    Appflow: Type[BotoClient]
    AppIntegrations: Type[BotoClient]
    Application_Autoscaling: Type[BotoClient]
    Application_Insights: Type[BotoClient]
    Applicationcostprofiler: Type[BotoClient]
    Appmesh: Type[BotoClient]
    Apprunner: Type[BotoClient]
    Appstream: Type[BotoClient]
    Appsync: Type[BotoClient]
    Arc_Zonal_Shift: Type[BotoClient]
    Athena: Type[BotoClient]
    AuditManager: Type[BotoClient]
    Autoscaling: Type[BotoClient]
    Autoscaling_Plans: Type[BotoClient]
    Backup: Type[BotoClient]
    Backup_Gateway: Type[BotoClient]
    BackupStorage: Type[BotoClient]
    Batch: Type[BotoClient]
    BillingConductor: Type[BotoClient]
    Braket: Type[BotoClient]
    Budgets: Type[BotoClient]
    Ce: Type[BotoClient]
    Chime: Type[BotoClient]
    Chime_Sdk_Identity: Type[BotoClient]
    Chime_Sdk_Media_Pipelines: Type[BotoClient]
    Chime_Sdk_Meetings: Type[BotoClient]
    Chime_Sdk_Messaging: Type[BotoClient]
    Chime_Sdk_Voice: Type[BotoClient]
    Cleanrooms: Type[BotoClient]
    Cloud9: Type[BotoClient]
    Cloudcontrol: Type[BotoClient]
    Clouddirectory: Type[BotoClient]
    Cloudformation: Type[BotoClient]
    Cloudfront: Type[BotoClient]
    Cloudhsm: Type[BotoClient]
    Cloudhsmv2: Type[BotoClient]
    Cloudsearch: Type[BotoClient]
    Cloudsearchdomain: Type[BotoClient]
    Cloudtrail: Type[BotoClient]
    Cloudtrail_Data: Type[BotoClient]
    Cloudwatch: Type[BotoClient]
    CodeArtifact: Type[BotoClient]
    CodeBuild: Type[BotoClient]
    CodeCatalyst: Type[BotoClient]
    CodeCommit: Type[BotoClient]
    CodeDeploy: Type[BotoClient]
    Codeguru_Reviewer: Type[BotoClient]
    CodeguruProfiler: Type[BotoClient]
    CodePipeline: Type[BotoClient]
    Codestar: Type[BotoClient]
    Codestar_Connections: Type[BotoClient]
    Codestar_Notifications: Type[BotoClient]
    Cognito_Identity: Type[BotoClient]
    Cognito_Idp: Type[BotoClient]
    Cognito_Sync: Type[BotoClient]
    Comprehend: Type[BotoClient]
    Comprehendmedical: Type[BotoClient]
    Compute_Optimizer: Type[BotoClient]
    Config: Type[BotoClient]
    Connect: Type[BotoClient]
    Connect_Contact_Lens: Type[BotoClient]
    ConnectCampaigns: Type[BotoClient]
    ConnectCases: Type[BotoClient]
    ConnectParticipant: Type[BotoClient]
    ControlTower: Type[BotoClient]
    Cur: Type[BotoClient]
    Customer_Profiles: Type[BotoClient]
    DataBrew: Type[BotoClient]
    DataExchange: Type[BotoClient]
    DataPipeline: Type[BotoClient]
    DataSync: Type[BotoClient]
    Dax: Type[BotoClient]
    Detective: Type[BotoClient]
    Devicefarm: Type[BotoClient]
    Devops_Guru: Type[BotoClient]
    DirectConnect: Type[BotoClient]
    Discovery: Type[BotoClient]
    Dlm: Type[BotoClient]
    Dms: Type[BotoClient]
    Docdb: Type[BotoClient]
    Docdb_Elastic: Type[BotoClient]
    Drs: Type[BotoClient]
    Ds: Type[BotoClient]
    DynamoDb: Type[BotoClient]
    DynamoDbStreams: Type[BotoClient]
    Ebs: Type[BotoClient]
    Ec2: Type[BotoClient]
    Ec2_Instance_Connect: Type[BotoClient]
    Ecr: Type[BotoClient]
    Ecr_Public: Type[BotoClient]
    Ecs: Type[BotoClient]
    Efs: Type[BotoClient]
    Eks: Type[BotoClient]
    Elastic_Inference: Type[BotoClient]
    Elasticache: Type[BotoClient]
    ElasticBeanstalk: Type[BotoClient]
    ElasticTranscoder: Type[BotoClient]
    Elb: Type[BotoClient]
    Elbv2: Type[BotoClient]
    Emr: Type[BotoClient]
    Emr_Containers: Type[BotoClient]
    Emr_Serverless: Type[BotoClient]
    Es: Type[BotoClient]
    Events: Type[BotoClient]
    Evidently: Type[BotoClient]
    Finspace: Type[BotoClient]
    Finspace_Data: Type[BotoClient]
    Firehose: Type[BotoClient]
    Fis: Type[BotoClient]
    Fms: Type[BotoClient]
    Forecast: Type[BotoClient]
    Forecastquery: Type[BotoClient]
    Frauddetector: Type[BotoClient]
    Fsx: Type[BotoClient]
    Gamelift: Type[BotoClient]
    Gamesparks: Type[BotoClient]
    Glacier: Type[BotoClient]
    Globalaccelerator: Type[BotoClient]
    Glue: Type[BotoClient]
    Grafana: Type[BotoClient]
    Greengrass: Type[BotoClient]
    Greengrassv2: Type[BotoClient]
    Groundstation: Type[BotoClient]
    Guardduty: Type[BotoClient]
    Health: Type[BotoClient]
    Healthlake: Type[BotoClient]
    Honeycode: Type[BotoClient]
    Iam: Type[BotoClient]
    IdentityStore: Type[BotoClient]
    ImageBuilder: Type[BotoClient]
    ImportExport: Type[BotoClient]
    Inspector: Type[BotoClient]
    Inspector2: Type[BotoClient]
    Iot: Type[BotoClient]
    Iot_Data: Type[BotoClient]
    Iot_Jobs_Data: Type[BotoClient]
    Iot_Roborunner: Type[BotoClient]
    Iot1Click_Devices: Type[BotoClient]
    Iot1Click_Projects: Type[BotoClient]
    IotAnalytics: Type[BotoClient]
    IotDeviceAdvisor: Type[BotoClient]
    IotEvents: Type[BotoClient]
    IotEvents_Data: Type[BotoClient]
    IotFleethub: Type[BotoClient]
    IotFleetwise: Type[BotoClient]
    IotSecureTunneling: Type[BotoClient]
    IotSitewise: Type[BotoClient]
    IotThingsgraph: Type[BotoClient]
    IotTwinmaker: Type[BotoClient]
    IotWireless: Type[BotoClient]
    Ivs: Type[BotoClient]
    Ivschat: Type[BotoClient]
    Kafka: Type[BotoClient]
    Kafkaconnect: Type[BotoClient]
    Kendra: Type[BotoClient]
    Kendra_Ranking: Type[BotoClient]
    Keyspaces: Type[BotoClient]
    Kinesis: Type[BotoClient]
    Kinesis_Video_Archived_Media: Type[BotoClient]
    Kinesis_Video_Media: Type[BotoClient]
    Kinesis_Video_Signaling: Type[BotoClient]
    Kinesis_Video_Webrtc_Storage: Type[BotoClient]
    KinesisAnalytics: Type[BotoClient]
    KinesisAnalyticsv2: Type[BotoClient]
    Kinesisvideo: Type[BotoClient]
    Kms: Type[BotoClient]
    Lakeformation: Type[BotoClient]
    # Lambda Is A Key-Word, Underscore Is Ignored.
    Lambda_: Type[BotoClient]
    Lex_Models: Type[BotoClient]
    Lex_Runtime: Type[BotoClient]
    Lexv2_Models: Type[BotoClient]
    Lexv2_Runtime: Type[BotoClient]
    License_Manager: Type[BotoClient]
    License_Manager_Linux_Subscriptions: Type[BotoClient]
    License_Manager_User_Subscriptions: Type[BotoClient]
    Lightsail: Type[BotoClient]
    Location: Type[BotoClient]
    Logs: Type[BotoClient]
    LookoutEquipment: Type[BotoClient]
    LookoutMetrics: Type[BotoClient]
    LookoutVision: Type[BotoClient]
    M2: Type[BotoClient]
    MachineLearning: Type[BotoClient]
    Macie: Type[BotoClient]
    Macie2: Type[BotoClient]
    ManagedBlockchain: Type[BotoClient]
    MarketPlace_Catalog: Type[BotoClient]
    MarketPlace_Entitlement: Type[BotoClient]
    MarketPlacecommerceanalytics: Type[BotoClient]
    MediaConnect: Type[BotoClient]
    MediaConvert: Type[BotoClient]
    MediaLive: Type[BotoClient]
    MediaPackage: Type[BotoClient]
    MediaPackage_Vod: Type[BotoClient]
    MediaStore: Type[BotoClient]
    MediaStore_Data: Type[BotoClient]
    MediaTailor: Type[BotoClient]
    MemoryDb: Type[BotoClient]
    MeteringMarketplace: Type[BotoClient]
    Mgh: Type[BotoClient]
    Mgn: Type[BotoClient]
    Migration_Hub_Refactor_Spaces: Type[BotoClient]
    MigrationHub_Config: Type[BotoClient]
    MigrationHubOrchestrator: Type[BotoClient]
    MigrationHubStrategy: Type[BotoClient]
    Mobile: Type[BotoClient]
    Mq: Type[BotoClient]
    Mturk: Type[BotoClient]
    Mwaa: Type[BotoClient]
    Neptune: Type[BotoClient]
    Network_Firewall: Type[BotoClient]
    Networkmanager: Type[BotoClient]
    Nimble: Type[BotoClient]
    Oam: Type[BotoClient]
    Omics: Type[BotoClient]
    Opensearch: Type[BotoClient]
    OpensearchServerless: Type[BotoClient]
    Opsworks: Type[BotoClient]
    Opsworkscm: Type[BotoClient]
    Organizations: Type[BotoClient]
    Outposts: Type[BotoClient]
    Panorama: Type[BotoClient]
    Personalize: Type[BotoClient]
    Personalize_Events: Type[BotoClient]
    Personalize_Runtime: Type[BotoClient]
    Pi: Type[BotoClient]
    Pinpoint: Type[BotoClient]
    Pinpoint_Email: Type[BotoClient]
    Pinpoint_Sms_Voice: Type[BotoClient]
    Pinpoint_Sms_Voice_V2: Type[BotoClient]
    Pipes: Type[BotoClient]
    Polly: Type[BotoClient]
    Pricing: Type[BotoClient]
    Privatenetworks: Type[BotoClient]
    Proton: Type[BotoClient]
    Qldb: Type[BotoClient]
    Qldb_Session: Type[BotoClient]
    Quicksight: Type[BotoClient]
    Ram: Type[BotoClient]
    Rbin: Type[BotoClient]
    Rds: Type[BotoClient]
    Rds_Data: Type[BotoClient]
    Redshift: Type[BotoClient]
    Redshift_Data: Type[BotoClient]
    Redshift_Serverless: Type[BotoClient]
    Rekognition: Type[BotoClient]
    Resiliencehub: Type[BotoClient]
    Resource_Explorer_2: Type[BotoClient]
    Resource_Groups: Type[BotoClient]
    ResourceGroupStaggingApi: Type[BotoClient]
    Robomaker: Type[BotoClient]
    Rolesanywhere: Type[BotoClient]
    Route53: Type[BotoClient]
    Route53_Recovery_Cluster: Type[BotoClient]
    Route53_Recovery_Control_Config: Type[BotoClient]
    Route53_Recovery_Readiness: Type[BotoClient]
    Route53Domains: Type[BotoClient]
    Route53Resolver: Type[BotoClient]
    Rum: Type[BotoClient]
    S3: Type[BotoClient]
    S3Control: Type[BotoClient]
    S3Outposts: Type[BotoClient]
    Sagemaker: Type[BotoClient]
    Sagemaker_A2I_Runtime: Type[BotoClient]
    Sagemaker_Edge: Type[BotoClient]
    Sagemaker_Featurestore_Runtime: Type[BotoClient]
    Sagemaker_Geospatial: Type[BotoClient]
    Sagemaker_Metrics: Type[BotoClient]
    Sagemaker_Runtime: Type[BotoClient]
    SavingsPlans: Type[BotoClient]
    Scheduler: Type[BotoClient]
    Schemas: Type[BotoClient]
    Sdb: Type[BotoClient]
    Secretsmanager: Type[BotoClient]
    Securityhub: Type[BotoClient]
    Securitylake: Type[BotoClient]
    Serverlessrepo: Type[BotoClient]
    Service_Quotas: Type[BotoClient]
    ServiceCatalog: Type[BotoClient]
    ServiceCatalog_Appregistry: Type[BotoClient]
    ServiceDiscovery: Type[BotoClient]
    Ses: Type[BotoClient]
    Sesv2: Type[BotoClient]
    Shield: Type[BotoClient]
    Signer: Type[BotoClient]
    Simspaceweaver: Type[BotoClient]
    Sms: Type[BotoClient]
    Sms_Voice: Type[BotoClient]
    Snow_Device_Management: Type[BotoClient]
    Snowball: Type[BotoClient]
    Sns: Type[BotoClient]
    Sqs: Type[BotoClient]
    Ssm: Type[BotoClient]
    Ssm_Contacts: Type[BotoClient]
    Ssm_Incidents: Type[BotoClient]
    Ssm_Sap: Type[BotoClient]
    Sso: Type[BotoClient]
    Sso_Admin: Type[BotoClient]
    Sso_Oidc: Type[BotoClient]
    StepFunctions: Type[BotoClient]
    StorageGateway: Type[BotoClient]
    Sts: Type[BotoClient]
    Support: Type[BotoClient]
    Support_App: Type[BotoClient]
    Swf: Type[BotoClient]
    Synthetics: Type[BotoClient]
    Textract: Type[BotoClient]
    Timestream_Query: Type[BotoClient]
    Timestream_Write: Type[BotoClient]
    Transcribe: Type[BotoClient]
    Transfer: Type[BotoClient]
    Translate: Type[BotoClient]
    Voice_Id: Type[BotoClient]
    Waf: Type[BotoClient]
    Waf_Regional: Type[BotoClient]
    Wafv2: Type[BotoClient]
    WellArchitected: Type[BotoClient]
    Wisdom: Type[BotoClient]
    Workdocs: Type[BotoClient]
    Worklink: Type[BotoClient]
    Workmail: Type[BotoClient]
    WorkmailMessageFlow: Type[BotoClient]
    Workspaces: Type[BotoClient]
    Workspaces_Web: Type[BotoClient]
    Xray: Type[BotoClient]

    # These annotations are only for IDE-type-completion;
    # any client boto supports will work regardless (even if not listed below).
    #
    # These are the boto client objects (start with lower-case letter)
    accessanalyzer: Any
    account: Any
    acm: Any
    acm_pca: Any
    alexaforbusiness: Any
    amp: Any
    amplify: Any
    amplifybackend: Any
    amplifyuibuilder: Any
    apigateway: Any
    apigatewaymanagementapi: Any
    apigatewayv2: Any
    appconfig: Any
    appconfigdata: Any
    appflow: Any
    appintegrations: Any
    application_autoscaling: Any
    application_insights: Any
    applicationcostprofiler: Any
    appmesh: Any
    apprunner: Any
    appstream: Any
    appsync: Any
    arc_zonal_shift: Any
    athena: Any
    auditmanager: Any
    autoscaling: Any
    autoscaling_plans: Any
    backup: Any
    backup_gateway: Any
    backupstorage: Any
    batch: Any
    billingconductor: Any
    braket: Any
    budgets: Any
    ce: Any
    chime: Any
    chime_sdk_identity: Any
    chime_sdk_media_pipelines: Any
    chime_sdk_meetings: Any
    chime_sdk_messaging: Any
    chime_sdk_voice: Any
    cleanrooms: Any
    cloud9: Any
    cloudcontrol: Any
    clouddirectory: Any
    cloudformation: Any
    cloudfront: Any
    cloudhsm: Any
    cloudhsmv2: Any
    cloudsearch: Any
    cloudsearchdomain: Any
    cloudtrail: Any
    cloudtrail_data: Any
    cloudwatch: Any
    codeartifact: Any
    codebuild: Any
    codecatalyst: Any
    codecommit: Any
    codedeploy: Any
    codeguru_reviewer: Any
    codeguruprofiler: Any
    codepipeline: Any
    codestar: Any
    codestar_connections: Any
    codestar_notifications: Any
    cognito_identity: Any
    cognito_idp: Any
    cognito_sync: Any
    comprehend: Any
    comprehendmedical: Any
    compute_optimizer: Any
    config: Any
    connect: Any
    connect_contact_lens: Any
    connectcampaigns: Any
    connectcases: Any
    connectparticipant: Any
    controltower: Any
    cur: Any
    customer_profiles: Any
    databrew: Any
    dataexchange: Any
    datapipeline: Any
    datasync: Any
    dax: Any
    detective: Any
    devicefarm: Any
    devops_guru: Any
    directconnect: Any
    discovery: Any
    dlm: Any
    dms: Any
    docdb: Any
    docdb_elastic: Any
    drs: Any
    ds: Any
    dynamodb: Any
    dynamodbstreams: Any
    ebs: Any
    ec2: Any
    ec2_instance_connect: Any
    ecr: Any
    ecr_public: Any
    ecs: Any
    efs: Any
    eks: Any
    elastic_inference: Any
    elasticache: Any
    elasticbeanstalk: Any
    elastictranscoder: Any
    elb: Any
    elbv2: Any
    emr: Any
    emr_containers: Any
    emr_serverless: Any
    es: Any
    events: Any
    evidently: Any
    finspace: Any
    finspace_data: Any
    firehose: Any
    fis: Any
    fms: Any
    forecast: Any
    forecastquery: Any
    frauddetector: Any
    fsx: Any
    gamelift: Any
    gamesparks: Any
    glacier: Any
    globalaccelerator: Any
    glue: Any
    grafana: Any
    greengrass: Any
    greengrassv2: Any
    groundstation: Any
    guardduty: Any
    health: Any
    healthlake: Any
    honeycode: Any
    iam: Any
    identitystore: Any
    imagebuilder: Any
    importexport: Any
    inspector: Any
    inspector2: Any
    iot: Any
    iot_data: Any
    iot_jobs_data: Any
    iot_roborunner: Any
    iot1click_devices: Any
    iot1click_projects: Any
    iotanalytics: Any
    iotdeviceadvisor: Any
    iotevents: Any
    iotevents_data: Any
    iotfleethub: Any
    iotfleetwise: Any
    iotsecuretunneling: Any
    iotsitewise: Any
    iotthingsgraph: Any
    iottwinmaker: Any
    iotwireless: Any
    ivs: Any
    ivschat: Any
    kafka: Any
    kafkaconnect: Any
    kendra: Any
    kendra_ranking: Any
    keyspaces: Any
    kinesis: Any
    kinesis_video_archived_media: Any
    kinesis_video_media: Any
    kinesis_video_signaling: Any
    kinesis_video_webrtc_storage: Any
    kinesisanalytics: Any
    kinesisanalyticsv2: Any
    kinesisvideo: Any
    kms: Any
    lakeformation: Any
    # Lambda is a key-word, underscore is ignored.
    lambda_: Any
    lex_models: Any
    lex_runtime: Any
    lexv2_models: Any
    lexv2_runtime: Any
    license_manager: Any
    license_manager_linux_subscriptions: Any
    license_manager_user_subscriptions: Any
    lightsail: Any
    location: Any
    logs: Any
    lookoutequipment: Any
    lookoutmetrics: Any
    lookoutvision: Any
    m2: Any
    machinelearning: Any
    macie: Any
    macie2: Any
    managedblockchain: Any
    marketplace_catalog: Any
    marketplace_entitlement: Any
    marketplacecommerceanalytics: Any
    mediaconnect: Any
    mediaconvert: Any
    medialive: Any
    mediapackage: Any
    mediapackage_vod: Any
    mediastore: Any
    mediastore_data: Any
    mediatailor: Any
    memorydb: Any
    meteringmarketplace: Any
    mgh: Any
    mgn: Any
    migration_hub_refactor_spaces: Any
    migrationhub_config: Any
    migrationhuborchestrator: Any
    migrationhubstrategy: Any
    mobile: Any
    mq: Any
    mturk: Any
    mwaa: Any
    neptune: Any
    network_firewall: Any
    networkmanager: Any
    nimble: Any
    oam: Any
    omics: Any
    opensearch: Any
    opensearchserverless: Any
    opsworks: Any
    opsworkscm: Any
    organizations: Any
    outposts: Any
    panorama: Any
    personalize: Any
    personalize_events: Any
    personalize_runtime: Any
    pi: Any
    pinpoint: Any
    pinpoint_email: Any
    pinpoint_sms_voice: Any
    pinpoint_sms_voice_v2: Any
    pipes: Any
    polly: Any
    pricing: Any
    privatenetworks: Any
    proton: Any
    qldb: Any
    qldb_session: Any
    quicksight: Any
    ram: Any
    rbin: Any
    rds: Any
    rds_data: Any
    redshift: Any
    redshift_data: Any
    redshift_serverless: Any
    rekognition: Any
    resiliencehub: Any
    resource_explorer_2: Any
    resource_groups: Any
    resourcegroupstaggingapi: Any
    robomaker: Any
    rolesanywhere: Any
    route53: Any
    route53_recovery_cluster: Any
    route53_recovery_control_config: Any
    route53_recovery_readiness: Any
    route53domains: Any
    route53resolver: Any
    rum: Any
    s3: Any
    s3control: Any
    s3outposts: Any
    sagemaker: Any
    sagemaker_a2i_runtime: Any
    sagemaker_edge: Any
    sagemaker_featurestore_runtime: Any
    sagemaker_geospatial: Any
    sagemaker_metrics: Any
    sagemaker_runtime: Any
    savingsplans: Any
    scheduler: Any
    schemas: Any
    sdb: Any
    secretsmanager: Any
    securityhub: Any
    securitylake: Any
    serverlessrepo: Any
    service_quotas: Any
    servicecatalog: Any
    servicecatalog_appregistry: Any
    servicediscovery: Any
    ses: Any
    sesv2: Any
    shield: Any
    signer: Any
    simspaceweaver: Any
    sms: Any
    sms_voice: Any
    snow_device_management: Any
    snowball: Any
    sns: Any
    sqs: Any
    ssm: Any
    ssm_contacts: Any
    ssm_incidents: Any
    ssm_sap: Any
    sso: Any
    sso_admin: Any
    sso_oidc: Any
    stepfunctions: Any
    storagegateway: Any
    sts: Any
    support: Any
    support_app: Any
    swf: Any
    synthetics: Any
    textract: Any
    timestream_query: Any
    timestream_write: Any
    transcribe: Any
    transfer: Any
    translate: Any
    voice_id: Any
    waf: Any
    waf_regional: Any
    wafv2: Any
    wellarchitected: Any
    wisdom: Any
    workdocs: Any
    worklink: Any
    workmail: Any
    workmailmessageflow: Any
    workspaces: Any
    workspaces_web: Any
    xray: Any

When you get an attribute off of me, I'll attempt to ask the boto3 library to allocate a client of the same type, and then store itself, so I return the same client again in the future.

Right now, we will lazily allocate a boto3 client per-thread, and we will use the per-thread shared boto3 session resource to do it (ie: _BotoSession.session).

You can also easily import and use the boto_clients proxy object (defined at top module-level).

You can use boto_clients exactly the same as using Dependency.grab(), making it more convenient to use since you can directly import boto_clients.

>>> from xboto import boto_clients
>>> # Showing here how you could use it:
>>> boto_clients.ssm.get_paginator(...)

If you have an aws client that uses a - for it's name, you can use an _ (underscore) instead. All underscores are changed to a - when looking up the aws client. You can also directly use the xboto.dependencies.BotoClients.load method, and use a - there.

Ancestors

Class variables

var AccessAnalyzer : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Account : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Acm : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Acm_Pca : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var AlexaForBusiness : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Amp : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Amplify : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var AmplifyBackend : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var AmplifyUiBuilder : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ApiGateway : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ApiGatewayManagementApi : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ApiGatewayV2 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var AppConfig : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var AppConfigData : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var AppIntegrations : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Appflow : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Application_Autoscaling : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Application_Insights : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Applicationcostprofiler : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Appmesh : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Apprunner : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Appstream : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Appsync : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Arc_Zonal_Shift : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Athena : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var AuditManager : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Autoscaling : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Autoscaling_Plans : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Backup : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var BackupStorage : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Backup_Gateway : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Batch : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var BillingConductor : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Braket : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Budgets : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ce : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Chime : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Chime_Sdk_Identity : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Chime_Sdk_Media_Pipelines : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Chime_Sdk_Meetings : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Chime_Sdk_Messaging : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Chime_Sdk_Voice : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cleanrooms : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cloud9 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cloudcontrol : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Clouddirectory : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cloudformation : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cloudfront : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cloudhsm : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cloudhsmv2 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cloudsearch : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cloudsearchdomain : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cloudtrail : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cloudtrail_Data : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cloudwatch : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var CodeArtifact : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var CodeBuild : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var CodeCatalyst : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var CodeCommit : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var CodeDeploy : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var CodePipeline : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var CodeguruProfiler : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Codeguru_Reviewer : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Codestar : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Codestar_Connections : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Codestar_Notifications : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cognito_Identity : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cognito_Idp : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cognito_Sync : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Comprehend : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Comprehendmedical : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Compute_Optimizer : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Config : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Connect : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ConnectCampaigns : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ConnectCases : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ConnectParticipant : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Connect_Contact_Lens : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ControlTower : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Cur : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Customer_Profiles : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var DataBrew : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var DataExchange : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var DataPipeline : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var DataSync : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Dax : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Detective : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Devicefarm : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Devops_Guru : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var DirectConnect : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Discovery : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Dlm : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Dms : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Docdb : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Docdb_Elastic : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Drs : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ds : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var DynamoDb : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var DynamoDbStreams : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ebs : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ec2 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ec2_Instance_Connect : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ecr : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ecr_Public : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ecs : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Efs : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Eks : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ElasticBeanstalk : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ElasticTranscoder : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Elastic_Inference : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Elasticache : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Elb : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Elbv2 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Emr : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Emr_Containers : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Emr_Serverless : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Es : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Events : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Evidently : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Finspace : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Finspace_Data : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Firehose : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Fis : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Fms : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Forecast : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Forecastquery : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Frauddetector : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Fsx : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Gamelift : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Gamesparks : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Glacier : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Globalaccelerator : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Glue : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Grafana : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Greengrass : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Greengrassv2 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Groundstation : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Guardduty : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Health : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Healthlake : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Honeycode : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Iam : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var IdentityStore : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ImageBuilder : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ImportExport : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Inspector : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Inspector2 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Iot : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Iot1Click_Devices : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Iot1Click_Projects : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var IotAnalytics : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var IotDeviceAdvisor : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var IotEvents : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var IotEvents_Data : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var IotFleethub : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var IotFleetwise : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var IotSecureTunneling : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var IotSitewise : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var IotThingsgraph : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var IotTwinmaker : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var IotWireless : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Iot_Data : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Iot_Jobs_Data : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Iot_Roborunner : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ivs : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ivschat : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Kafka : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Kafkaconnect : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Kendra : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Kendra_Ranking : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Keyspaces : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Kinesis : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var KinesisAnalytics : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var KinesisAnalyticsv2 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Kinesis_Video_Archived_Media : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Kinesis_Video_Media : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Kinesis_Video_Signaling : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Kinesis_Video_Webrtc_Storage : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Kinesisvideo : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Kms : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Lakeformation : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Lambda_ : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Lex_Models : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Lex_Runtime : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Lexv2_Models : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Lexv2_Runtime : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var License_Manager : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var License_Manager_Linux_Subscriptions : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var License_Manager_User_Subscriptions : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Lightsail : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Location : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Logs : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var LookoutEquipment : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var LookoutMetrics : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var LookoutVision : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var M2 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MachineLearning : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Macie : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Macie2 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ManagedBlockchain : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MarketPlace_Catalog : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MarketPlace_Entitlement : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MarketPlacecommerceanalytics : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MediaConnect : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MediaConvert : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MediaLive : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MediaPackage : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MediaPackage_Vod : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MediaStore : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MediaStore_Data : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MediaTailor : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MemoryDb : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MeteringMarketplace : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Mgh : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Mgn : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MigrationHubOrchestrator : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MigrationHubStrategy : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var MigrationHub_Config : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Migration_Hub_Refactor_Spaces : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Mobile : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Mq : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Mturk : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Mwaa : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Neptune : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Network_Firewall : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Networkmanager : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Nimble : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Oam : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Omics : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Opensearch : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var OpensearchServerless : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Opsworks : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Opsworkscm : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Organizations : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Outposts : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Panorama : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Personalize : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Personalize_Events : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Personalize_Runtime : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Pi : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Pinpoint : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Pinpoint_Email : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Pinpoint_Sms_Voice : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Pinpoint_Sms_Voice_V2 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Pipes : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Polly : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Pricing : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Privatenetworks : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Proton : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Qldb : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Qldb_Session : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Quicksight : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ram : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Rbin : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Rds : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Rds_Data : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Redshift : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Redshift_Data : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Redshift_Serverless : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Rekognition : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Resiliencehub : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ResourceGroupStaggingApi : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Resource_Explorer_2 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Resource_Groups : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Robomaker : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Rolesanywhere : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Route53 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Route53Domains : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Route53Resolver : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Route53_Recovery_Cluster : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Route53_Recovery_Control_Config : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Route53_Recovery_Readiness : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Rum : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var S3 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var S3Control : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var S3Outposts : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sagemaker : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sagemaker_A2I_Runtime : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sagemaker_Edge : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sagemaker_Featurestore_Runtime : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sagemaker_Geospatial : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sagemaker_Metrics : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sagemaker_Runtime : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var SavingsPlans : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Scheduler : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Schemas : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sdb : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Secretsmanager : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Securityhub : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Securitylake : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Serverlessrepo : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ServiceCatalog : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ServiceCatalog_Appregistry : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var ServiceDiscovery : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Service_Quotas : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ses : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sesv2 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Shield : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Signer : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Simspaceweaver : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sms : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sms_Voice : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Snow_Device_Management : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Snowball : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sns : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sqs : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ssm : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ssm_Contacts : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ssm_Incidents : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ssm_Sap : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sso : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sso_Admin : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sso_Oidc : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var StepFunctions : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var StorageGateway : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sts : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Support : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Support_App : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Swf : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Synthetics : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Textract : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Timestream_Query : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Timestream_Write : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Transcribe : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Transfer : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Translate : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Voice_Id : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Waf : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Waf_Regional : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Wafv2 : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var WellArchitected : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Wisdom : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Workdocs : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Workmail : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var WorkmailMessageFlow : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Workspaces : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Workspaces_Web : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Xray : Type[BotoClient]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var accessanalyzer : Any

The type of the None singleton.

var account : Any

The type of the None singleton.

var acm : Any

The type of the None singleton.

var acm_pca : Any

The type of the None singleton.

var alexaforbusiness : Any

The type of the None singleton.

var amp : Any

The type of the None singleton.

var amplify : Any

The type of the None singleton.

var amplifybackend : Any

The type of the None singleton.

var amplifyuibuilder : Any

The type of the None singleton.

var apigateway : Any

The type of the None singleton.

var apigatewaymanagementapi : Any

The type of the None singleton.

var apigatewayv2 : Any

The type of the None singleton.

var appconfig : Any

The type of the None singleton.

var appconfigdata : Any

The type of the None singleton.

var appflow : Any

The type of the None singleton.

var appintegrations : Any

The type of the None singleton.

var application_autoscaling : Any

The type of the None singleton.

var application_insights : Any

The type of the None singleton.

var applicationcostprofiler : Any

The type of the None singleton.

var appmesh : Any

The type of the None singleton.

var apprunner : Any

The type of the None singleton.

var appstream : Any

The type of the None singleton.

var appsync : Any

The type of the None singleton.

var arc_zonal_shift : Any

The type of the None singleton.

var athena : Any

The type of the None singleton.

var auditmanager : Any

The type of the None singleton.

var autoscaling : Any

The type of the None singleton.

var autoscaling_plans : Any

The type of the None singleton.

var backup : Any

The type of the None singleton.

var backup_gateway : Any

The type of the None singleton.

var backupstorage : Any

The type of the None singleton.

var batch : Any

The type of the None singleton.

var billingconductor : Any

The type of the None singleton.

var braket : Any

The type of the None singleton.

var budgets : Any

The type of the None singleton.

var ce : Any

The type of the None singleton.

var chime : Any

The type of the None singleton.

var chime_sdk_identity : Any

The type of the None singleton.

var chime_sdk_media_pipelines : Any

The type of the None singleton.

var chime_sdk_meetings : Any

The type of the None singleton.

var chime_sdk_messaging : Any

The type of the None singleton.

var chime_sdk_voice : Any

The type of the None singleton.

var cleanrooms : Any

The type of the None singleton.

var cloud9 : Any

The type of the None singleton.

var cloudcontrol : Any

The type of the None singleton.

var clouddirectory : Any

The type of the None singleton.

var cloudformation : Any

The type of the None singleton.

var cloudfront : Any

The type of the None singleton.

var cloudhsm : Any

The type of the None singleton.

var cloudhsmv2 : Any

The type of the None singleton.

var cloudsearch : Any

The type of the None singleton.

var cloudsearchdomain : Any

The type of the None singleton.

var cloudtrail : Any

The type of the None singleton.

var cloudtrail_data : Any

The type of the None singleton.

var cloudwatch : Any

The type of the None singleton.

var codeartifact : Any

The type of the None singleton.

var codebuild : Any

The type of the None singleton.

var codecatalyst : Any

The type of the None singleton.

var codecommit : Any

The type of the None singleton.

var codedeploy : Any

The type of the None singleton.

var codeguru_reviewer : Any

The type of the None singleton.

var codeguruprofiler : Any

The type of the None singleton.

var codepipeline : Any

The type of the None singleton.

var codestar : Any

The type of the None singleton.

var codestar_connections : Any

The type of the None singleton.

var codestar_notifications : Any

The type of the None singleton.

var cognito_identity : Any

The type of the None singleton.

var cognito_idp : Any

The type of the None singleton.

var cognito_sync : Any

The type of the None singleton.

var comprehend : Any

The type of the None singleton.

var comprehendmedical : Any

The type of the None singleton.

var compute_optimizer : Any

The type of the None singleton.

var config : Any

The type of the None singleton.

var connect : Any

The type of the None singleton.

var connect_contact_lens : Any

The type of the None singleton.

var connectcampaigns : Any

The type of the None singleton.

var connectcases : Any

The type of the None singleton.

var connectparticipant : Any

The type of the None singleton.

var controltower : Any

The type of the None singleton.

var cur : Any

The type of the None singleton.

var customer_profiles : Any

The type of the None singleton.

var databrew : Any

The type of the None singleton.

var dataexchange : Any

The type of the None singleton.

var datapipeline : Any

The type of the None singleton.

var datasync : Any

The type of the None singleton.

var dax : Any

The type of the None singleton.

var detective : Any

The type of the None singleton.

var devicefarm : Any

The type of the None singleton.

var devops_guru : Any

The type of the None singleton.

var directconnect : Any

The type of the None singleton.

var discovery : Any

The type of the None singleton.

var dlm : Any

The type of the None singleton.

var dms : Any

The type of the None singleton.

var docdb : Any

The type of the None singleton.

var docdb_elastic : Any

The type of the None singleton.

var drs : Any

The type of the None singleton.

var ds : Any

The type of the None singleton.

var dynamodb : Any

The type of the None singleton.

var dynamodbstreams : Any

The type of the None singleton.

var ebs : Any

The type of the None singleton.

var ec2 : Any

The type of the None singleton.

var ec2_instance_connect : Any

The type of the None singleton.

var ecr : Any

The type of the None singleton.

var ecr_public : Any

The type of the None singleton.

var ecs : Any

The type of the None singleton.

var efs : Any

The type of the None singleton.

var eks : Any

The type of the None singleton.

var elastic_inference : Any

The type of the None singleton.

var elasticache : Any

The type of the None singleton.

var elasticbeanstalk : Any

The type of the None singleton.

var elastictranscoder : Any

The type of the None singleton.

var elb : Any

The type of the None singleton.

var elbv2 : Any

The type of the None singleton.

var emr : Any

The type of the None singleton.

var emr_containers : Any

The type of the None singleton.

var emr_serverless : Any

The type of the None singleton.

var es : Any

The type of the None singleton.

var events : Any

The type of the None singleton.

var evidently : Any

The type of the None singleton.

var finspace : Any

The type of the None singleton.

var finspace_data : Any

The type of the None singleton.

var firehose : Any

The type of the None singleton.

var fis : Any

The type of the None singleton.

var fms : Any

The type of the None singleton.

var forecast : Any

The type of the None singleton.

var forecastquery : Any

The type of the None singleton.

var frauddetector : Any

The type of the None singleton.

var fsx : Any

The type of the None singleton.

var gamelift : Any

The type of the None singleton.

var gamesparks : Any

The type of the None singleton.

var glacier : Any

The type of the None singleton.

var globalaccelerator : Any

The type of the None singleton.

var glue : Any

The type of the None singleton.

var grafana : Any

The type of the None singleton.

var greengrass : Any

The type of the None singleton.

var greengrassv2 : Any

The type of the None singleton.

var groundstation : Any

The type of the None singleton.

var guardduty : Any

The type of the None singleton.

var health : Any

The type of the None singleton.

var healthlake : Any

The type of the None singleton.

var honeycode : Any

The type of the None singleton.

var iam : Any

The type of the None singleton.

var identitystore : Any

The type of the None singleton.

var imagebuilder : Any

The type of the None singleton.

var importexport : Any

The type of the None singleton.

var inspector : Any

The type of the None singleton.

var inspector2 : Any

The type of the None singleton.

var iot : Any

The type of the None singleton.

var iot1click_devices : Any

The type of the None singleton.

var iot1click_projects : Any

The type of the None singleton.

var iot_data : Any

The type of the None singleton.

var iot_jobs_data : Any

The type of the None singleton.

var iot_roborunner : Any

The type of the None singleton.

var iotanalytics : Any

The type of the None singleton.

var iotdeviceadvisor : Any

The type of the None singleton.

var iotevents : Any

The type of the None singleton.

var iotevents_data : Any

The type of the None singleton.

var iotfleethub : Any

The type of the None singleton.

var iotfleetwise : Any

The type of the None singleton.

var iotsecuretunneling : Any

The type of the None singleton.

var iotsitewise : Any

The type of the None singleton.

var iotthingsgraph : Any

The type of the None singleton.

var iottwinmaker : Any

The type of the None singleton.

var iotwireless : Any

The type of the None singleton.

var ivs : Any

The type of the None singleton.

var ivschat : Any

The type of the None singleton.

var kafka : Any

The type of the None singleton.

var kafkaconnect : Any

The type of the None singleton.

var kendra : Any

The type of the None singleton.

var kendra_ranking : Any

The type of the None singleton.

var keyspaces : Any

The type of the None singleton.

var kinesis : Any

The type of the None singleton.

var kinesis_video_archived_media : Any

The type of the None singleton.

var kinesis_video_media : Any

The type of the None singleton.

var kinesis_video_signaling : Any

The type of the None singleton.

var kinesis_video_webrtc_storage : Any

The type of the None singleton.

var kinesisanalytics : Any

The type of the None singleton.

var kinesisanalyticsv2 : Any

The type of the None singleton.

var kinesisvideo : Any

The type of the None singleton.

var kms : Any

The type of the None singleton.

var lakeformation : Any

The type of the None singleton.

var lambda_ : Any

The type of the None singleton.

var lex_models : Any

The type of the None singleton.

var lex_runtime : Any

The type of the None singleton.

var lexv2_models : Any

The type of the None singleton.

var lexv2_runtime : Any

The type of the None singleton.

var license_manager : Any

The type of the None singleton.

var license_manager_linux_subscriptions : Any

The type of the None singleton.

var license_manager_user_subscriptions : Any

The type of the None singleton.

var lightsail : Any

The type of the None singleton.

var location : Any

The type of the None singleton.

var logs : Any

The type of the None singleton.

var lookoutequipment : Any

The type of the None singleton.

var lookoutmetrics : Any

The type of the None singleton.

var lookoutvision : Any

The type of the None singleton.

var m2 : Any

The type of the None singleton.

var machinelearning : Any

The type of the None singleton.

var macie : Any

The type of the None singleton.

var macie2 : Any

The type of the None singleton.

var managedblockchain : Any

The type of the None singleton.

var marketplace_catalog : Any

The type of the None singleton.

var marketplace_entitlement : Any

The type of the None singleton.

var marketplacecommerceanalytics : Any

The type of the None singleton.

var mediaconnect : Any

The type of the None singleton.

var mediaconvert : Any

The type of the None singleton.

var medialive : Any

The type of the None singleton.

var mediapackage : Any

The type of the None singleton.

var mediapackage_vod : Any

The type of the None singleton.

var mediastore : Any

The type of the None singleton.

var mediastore_data : Any

The type of the None singleton.

var mediatailor : Any

The type of the None singleton.

var memorydb : Any

The type of the None singleton.

var meteringmarketplace : Any

The type of the None singleton.

var mgh : Any

The type of the None singleton.

var mgn : Any

The type of the None singleton.

var migration_hub_refactor_spaces : Any

The type of the None singleton.

var migrationhub_config : Any

The type of the None singleton.

var migrationhuborchestrator : Any

The type of the None singleton.

var migrationhubstrategy : Any

The type of the None singleton.

var mobile : Any

The type of the None singleton.

var mq : Any

The type of the None singleton.

var mturk : Any

The type of the None singleton.

var mwaa : Any

The type of the None singleton.

var neptune : Any

The type of the None singleton.

var network_firewall : Any

The type of the None singleton.

var networkmanager : Any

The type of the None singleton.

var nimble : Any

The type of the None singleton.

var oam : Any

The type of the None singleton.

var omics : Any

The type of the None singleton.

var opensearch : Any

The type of the None singleton.

var opensearchserverless : Any

The type of the None singleton.

var opsworks : Any

The type of the None singleton.

var opsworkscm : Any

The type of the None singleton.

var organizations : Any

The type of the None singleton.

var outposts : Any

The type of the None singleton.

var panorama : Any

The type of the None singleton.

var personalize : Any

The type of the None singleton.

var personalize_events : Any

The type of the None singleton.

var personalize_runtime : Any

The type of the None singleton.

var pi : Any

The type of the None singleton.

var pinpoint : Any

The type of the None singleton.

var pinpoint_email : Any

The type of the None singleton.

var pinpoint_sms_voice : Any

The type of the None singleton.

var pinpoint_sms_voice_v2 : Any

The type of the None singleton.

var pipes : Any

The type of the None singleton.

var polly : Any

The type of the None singleton.

var pricing : Any

The type of the None singleton.

var privatenetworks : Any

The type of the None singleton.

var proton : Any

The type of the None singleton.

var qldb : Any

The type of the None singleton.

var qldb_session : Any

The type of the None singleton.

var quicksight : Any

The type of the None singleton.

var ram : Any

The type of the None singleton.

var rbin : Any

The type of the None singleton.

var rds : Any

The type of the None singleton.

var rds_data : Any

The type of the None singleton.

var redshift : Any

The type of the None singleton.

var redshift_data : Any

The type of the None singleton.

var redshift_serverless : Any

The type of the None singleton.

var rekognition : Any

The type of the None singleton.

var resiliencehub : Any

The type of the None singleton.

var resource_explorer_2 : Any

The type of the None singleton.

var resource_groups : Any

The type of the None singleton.

var resourcegroupstaggingapi : Any

The type of the None singleton.

var robomaker : Any

The type of the None singleton.

var rolesanywhere : Any

The type of the None singleton.

var route53 : Any

The type of the None singleton.

var route53_recovery_cluster : Any

The type of the None singleton.

var route53_recovery_control_config : Any

The type of the None singleton.

var route53_recovery_readiness : Any

The type of the None singleton.

var route53domains : Any

The type of the None singleton.

var route53resolver : Any

The type of the None singleton.

var rum : Any

The type of the None singleton.

var s3 : Any

The type of the None singleton.

var s3control : Any

The type of the None singleton.

var s3outposts : Any

The type of the None singleton.

var sagemaker : Any

The type of the None singleton.

var sagemaker_a2i_runtime : Any

The type of the None singleton.

var sagemaker_edge : Any

The type of the None singleton.

var sagemaker_featurestore_runtime : Any

The type of the None singleton.

var sagemaker_geospatial : Any

The type of the None singleton.

var sagemaker_metrics : Any

The type of the None singleton.

var sagemaker_runtime : Any

The type of the None singleton.

var savingsplans : Any

The type of the None singleton.

var scheduler : Any

The type of the None singleton.

var schemas : Any

The type of the None singleton.

var sdb : Any

The type of the None singleton.

var secretsmanager : Any

The type of the None singleton.

var securityhub : Any

The type of the None singleton.

var securitylake : Any

The type of the None singleton.

var serverlessrepo : Any

The type of the None singleton.

var service_quotas : Any

The type of the None singleton.

var servicecatalog : Any

The type of the None singleton.

var servicecatalog_appregistry : Any

The type of the None singleton.

var servicediscovery : Any

The type of the None singleton.

var ses : Any

The type of the None singleton.

var sesv2 : Any

The type of the None singleton.

var shield : Any

The type of the None singleton.

var signer : Any

The type of the None singleton.

var simspaceweaver : Any

The type of the None singleton.

var sms : Any

The type of the None singleton.

var sms_voice : Any

The type of the None singleton.

var snow_device_management : Any

The type of the None singleton.

var snowball : Any

The type of the None singleton.

var sns : Any

The type of the None singleton.

var sqs : Any

The type of the None singleton.

var ssm : Any

The type of the None singleton.

var ssm_contacts : Any

The type of the None singleton.

var ssm_incidents : Any

The type of the None singleton.

var ssm_sap : Any

The type of the None singleton.

var sso : Any

The type of the None singleton.

var sso_admin : Any

The type of the None singleton.

var sso_oidc : Any

The type of the None singleton.

var stepfunctions : Any

The type of the None singleton.

var storagegateway : Any

The type of the None singleton.

var sts : Any

The type of the None singleton.

var support : Any

The type of the None singleton.

var support_app : Any

The type of the None singleton.

var swf : Any

The type of the None singleton.

var synthetics : Any

The type of the None singleton.

var textract : Any

The type of the None singleton.

var timestream_query : Any

The type of the None singleton.

var timestream_write : Any

The type of the None singleton.

var transcribe : Any

The type of the None singleton.

var transfer : Any

The type of the None singleton.

var translate : Any

The type of the None singleton.

var voice_id : Any

The type of the None singleton.

var waf : Any

The type of the None singleton.

var waf_regional : Any

The type of the None singleton.

var wafv2 : Any

The type of the None singleton.

var wellarchitected : Any

The type of the None singleton.

var wisdom : Any

The type of the None singleton.

var workdocs : Any

The type of the None singleton.

The type of the None singleton.

var workmail : Any

The type of the None singleton.

var workmailmessageflow : Any

The type of the None singleton.

var workspaces : Any

The type of the None singleton.

var workspaces_web : Any

The type of the None singleton.

var xray : Any

The type of the None singleton.

Static methods

def __init_subclass__(thread_sharable: bool | DefaultType = Default,
remove_between_unittests: bool | DefaultType = Default,
attributes_to_skip_while_copying: Iterable[str] | None = Default,
**kwargs)

Inherited from: Dependency.__init_subclass__

Args

remove_between_unittests
If False (default): Dependency will be removed from global context before/after as each individual …
def grab() ‑> ~T

Inherited from: Dependency.grab

Gets a potentially shared dependency from the current udpend.context.XContext

def proxy() ‑> ~R

Inherited from: Dependency.proxy

Returns a proxy-object, that when and attribute is asked for, it will proxy it to the current object of cls

def proxy_attribute(attribute_name: str) ‑> Any

Inherited from: Dependency.proxy_attribute

Returns a proxy-object, that when and attribute is asked for, it will proxy it to the current attribute value on the current object of cls

Instance variables

var obj : ClassVar[Self]

Inherited from: Dependency.obj

class property/attribute that will return the current dependency for the subclass it's asked on by calling Dependency.grab, passing no extra …

Methods

def __call__(self, func)

Inherited from: Dependency.__call__

This makes Resource subclasses have an ability to be used as function decorators by default unless this method is overriden to provide some other …

def __copy__(self)

Inherited from: Dependency.__copy__

Basic shallow copy protection (I am wondering if I should just remove this default copy code) …

class BotoResource (region_name=None,
api_version=None,
use_ssl=None,
verify=None,
endpoint_url=None,
aws_access_key_id=None,
aws_secret_access_key=None,
aws_session_token=None,
config=None,
**boto_kwargs)
Expand source code
class BotoResource(_BaseBotoClientOrResource, boto_kind='resource'):
    @property
    def boto_resource(self):
        return self.get()

    @classmethod
    def get_dependency_cls(cls, boto_name: str) -> 'Type[BotoResource]':
        return cls._get_dependency_cls(boto_name)

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

You can specify any of the boto client/resource args, the known ones have been specififed and documented out.

If there are ones in the future that are new or we don't know about, you can still specify them, they will be passed to us in boto_kwargs, which will be used as addtional kwargs when creating new boto client/resource.

Args

region_name
The name of the region associated with the client. A client is associated with a single region.
api_version
The API version to use. By default, botocore will use the latest API version when creating a client.You only need to specify this parameter if you want to use a previous API version of the client.
use_ssl
Whether or not to use SSL. By default, SSL is used. Note that not all services support non-ssl connections.
verify

Whether or not to verify SSL certificates. By default SSL certificates are verified. You can provide the following values:

  • False - do not validate SSL certificates. SSL will still be used (unless use_ssl is False), but SSL certificates will not be verified.
  • path/to/cert/bundle.pem - A filename of the CA cert bundle to uses. You can specify this argument if you want to use a different CA cert bundle than the one used by botocore.
endpoint_url
The complete URL to use for the constructed client. Normally, botocore will automatically construct the appropriate URL to use when communicating with a service. You can specify a complete URL (including the "http/https" scheme) to override this behavior. If this value is provided, then use_ssl is ignored.
aws_access_key_id
The access key to use when creating the client. This is entirely optional, and if not provided, the credentials configured for the session will automatically be used. You only need to provide this argument if you want to override the credentials used for this specific client.
aws_secret_access_key
The secret key to use when creating the client. Same semantics as aws_access_key_id above.
aws_session_token
The session token to use when creating the client. Same semantics as aws_access_key_id above.
config
Advanced client configuration options. If region_name is specified in the client config, its value will take precedence over environment variables and configuration values, but not over a region_name value passed explicitly to the method. If user_agent_extra is specified in the client config, it overrides the default user_agent_extra provided by the resource API. See botocore config documentation for more details.

**boto_kwargs:

Ancestors

  • xboto.dependencies._BaseBotoClientOrResource
  • Dependency

Subclasses

  • xboto.dependencies.CloudformationResource
  • xboto.dependencies.CloudwatchResource
  • xboto.dependencies.DynamodbResource
  • xboto.dependencies.Ec2Resource
  • xboto.dependencies.GlacierResource
  • xboto.dependencies.IamResource
  • xboto.dependencies.NsResource
  • xboto.dependencies.OpsworksResource
  • xboto.dependencies.S3Resource
  • xboto.dependencies.SqsResource

Static methods

def __init_subclass__(thread_sharable: bool | DefaultType = Default,
remove_between_unittests: bool | DefaultType = Default,
attributes_to_skip_while_copying: Iterable[str] | None = Default,
**kwargs)

Inherited from: Dependency.__init_subclass__

Args

remove_between_unittests
If False (default): Dependency will be removed from global context before/after as each individual …
def get_dependency_cls(boto_name: str) ‑> Type[BotoResource]
def grab() ‑> ~T

Inherited from: Dependency.grab

Gets a potentially shared dependency from the current udpend.context.XContext

def proxy() ‑> ~R

Inherited from: Dependency.proxy

Returns a proxy-object, that when and attribute is asked for, it will proxy it to the current object of cls

def proxy_attribute(attribute_name: str) ‑> Any

Inherited from: Dependency.proxy_attribute

Returns a proxy-object, that when and attribute is asked for, it will proxy it to the current attribute value on the current object of cls

Instance variables

prop boto_resource
Expand source code
@property
def boto_resource(self):
    return self.get()
var obj : ClassVar[Self]

Inherited from: Dependency.obj

class property/attribute that will return the current dependency for the subclass it's asked on by calling Dependency.grab, passing no extra …

Methods

def __call__(self, func)

Inherited from: Dependency.__call__

This makes Resource subclasses have an ability to be used as function decorators by default unless this method is overriden to provide some other …

def __copy__(self)

Inherited from: Dependency.__copy__

Basic shallow copy protection (I am wondering if I should just remove this default copy code) …

class BotoResources
Expand source code
class BotoResources(_Loader, boto_dependency_class=BotoResource):
    """
    When you get an attribute off of me, I'll attempt to ask the boto3 library to allocate
    a resource of the same type, and then store itself, so I return the same resource again
    in the future.

    Right now, we will lazily allocate a boto3 resource per-thread, and we will use the
    per-thread shared boto3 session resource to do it (ie: `_BotoSession.session`).

    You can also easily import and use the `boto_resources` proxy object
    (defined at top module-level).

    You can use `boto_resources` exactly the same as using `BotoResources.grab()`,
    making it more convenient to use since you can directly import `boto_resources`.

    >>> from xboto import boto_resources
    >>> # Showing here how you could use it to get a Table resource:
    >>> table = boto_resources.dynamodb.Table("some-table")

    If you have an aws resource that uses a `-` for it's name, you can use an `_` (underscore)
    instead.
    All underscores are changed to a `-` when looking up the aws resource.
    You can also directly use the `xboto.dependencies.BotoResources.load` method, and use a `-`
    there.
    """

    def _lookup(self, module, **kwargs):
        return BotoResource.get_dependency_cls(module).grab().boto_resource

    # These annotations are only for IDE-type-completion;
    # any client boto supports will work regardless (even if not listed below).
    #
    # These are the xyn-resource `Resource` types/classes; ie: BotoResource subclasses
    # (start with upper-case letter):
    DynamoDB: Type[BotoResource]
    CloudFormation: Type[BotoResource]
    CloudWatch: Type[BotoResource]
    Ec2: Type[BotoResource]
    Glacier: Type[BotoResource]
    Iam: Type[BotoResource]
    OpsWorks: Type[BotoResource]
    S3: Type[BotoResource]
    Ns: Type[BotoResource]
    Sqs: Type[BotoResource]

    # These annotations are only for IDE-type-completion;
    # any client boto supports will work regardless (even if not listed below).
    #
    # These are the boto resource objects (start with lower-case letter):
    dynamodb: Any
    cloudformation: Any
    cloudwatch: Any
    ec2: Any
    glacier: Any
    iam: Any
    opsworks: Any
    s3: Any
    ns: Any
    sqs: Any

When you get an attribute off of me, I'll attempt to ask the boto3 library to allocate a resource of the same type, and then store itself, so I return the same resource again in the future.

Right now, we will lazily allocate a boto3 resource per-thread, and we will use the per-thread shared boto3 session resource to do it (ie: _BotoSession.session).

You can also easily import and use the boto_resources proxy object (defined at top module-level).

You can use boto_resources exactly the same as using Dependency.grab(), making it more convenient to use since you can directly import boto_resources.

>>> from xboto import boto_resources
>>> # Showing here how you could use it to get a Table resource:
>>> table = boto_resources.dynamodb.Table("some-table")

If you have an aws resource that uses a - for it's name, you can use an _ (underscore) instead. All underscores are changed to a - when looking up the aws resource. You can also directly use the xboto.dependencies.BotoResources.load method, and use a - there.

Ancestors

Class variables

var CloudFormation : Type[BotoResource]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var CloudWatch : Type[BotoResource]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var DynamoDB : Type[BotoResource]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ec2 : Type[BotoResource]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Glacier : Type[BotoResource]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Iam : Type[BotoResource]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Ns : Type[BotoResource]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var OpsWorks : Type[BotoResource]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var S3 : Type[BotoResource]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var Sqs : Type[BotoResource]

If you have not already done so, you should also read the xinject project's README.md for an overview of the library before diving into the below text, that's more of like reference material.

Summary

Allows you to create subclasses that act as sharable dependencies. Things that should stick around and should be created lazily.

Also allows code to temporarily create, customize and activate a dependency if you don't want the customization to stick around permanently. You can do it without your or other code needing to be aware of each other.

This helps promote code decoupling, since it's so easy to make a Resource activate it as the 'current' version to use.

The only coupling that takes place is to the Resource sub-class it's self.

You can also easily have each thread lazily create seperate instance of your Resource, by inheriting from DependencyPerThread.

Each separate piece of code that uses a particular Resource subclass can be completely unaware of each other, and yet each one can take advantage of the shared dependency.

This means that Resource can help cover dependency-injection use-cases.

Overview

A Resource represents an object in a XContext. Generally, dependencies that are added/created inside a XContext inherit from this abstract base Resource class, but are not required too. Resource just adds some class-level conveince methods and configuratino options. Inheriting from Resource also helps self-document that it's a Resource.

See Resources at top of this module for a general overview of how dependencies and XContext's work. You should also read the xinject project's README.md for a high-level overview. The text below is more like plain refrence matrial.

Get the current dependency via Resource.dependency, you can call it on sub-class/concreate dependency type, like so:

>>> from xinject import Dependency
>>> class MyConfig(Dependency):
...     some_setting: str = "default-setting-string"
>>>
>>> MyConfig.grab().some_setting

By default, Resource's act like a singletons; in that child contexs will simply get the same instance of the dependency that the parent context has.

If you inherit from this class, when you have Resource.dependency called on you, we will do our best to ensure that the same object instance is returned every time (there are two exceptions, keep reading).

These dependencies are stored in the current XContext's parent. What happens is:

If the current XContext and none of their parents have this object and it's asked for (like what happens when Resource.dependency is called on it), it will be created in the deepest/oldest parent XContext.

This is the first parent XContext who's XContext.parent is None. That way it should be visible to everyone on the current thread since it will normally be created in the app-root XContext.

If the Dependency can't be shared between multiple threads, creation would normally happen at the thread-root XContext instead of the app-root one.

If we don't already exist in any parent, then we must be created the first time we are asked for. Normally it will simply be a direct call the dependency-type being requested, this is the normal way to create objects in python:

>>> class MyResource(Dependency):
>>>     pass
>>>
>>> MyResource.grab()

When that last line is executed, and the current or any parent context has a MyResource dependency; XContext will simply create one via calling the dependency type:

>>> MyResource()

You can allocate the dependency yourself with custom options and add it to the XContext your self.

Here are the various ways to do that, via:

  • XContext.add Adds dependency to a specific XContext that already exists (or replaces if one has already been directly added in the past to that specific Context). When/While XContext is active, these added dependencies will be the current ones.

  • Decorator, ie: @MyResource()

    >>> from xny_config import Config, config
    >>>
    >>> @DependencySubclass(service="override-service-name")
    >>> def my_method():
    >>>    assert config.service == "override-service-name"
    
  • via a with statement.

    >>> def my_method():
    >>>    with @DependencySubclass(service="override-service-name")
    >>>         assert config.service == "override-service-name"
    
  • multiple in single statement by making your own XContext directly:

    >>> def my_method():
    >>>     with @XContext([
    >>>         DependencySubclass(service="override-service-name"),
    >>>         SomeOtherDep(name='new-name')
    >>>     ]):
    >>>         assert config.service == "override-service-name"
    

Background on Unit Testing

By default, unit tests always create a new blank XContext with parent=None. THis is done by an autouse fixture (xinject_test_context()) THis forces every unit test run to create new dependencies when they are asked for (lazily).

This fixture is used automatically for each unit test, it clears the app-root XContext, removes all current thread-root XContext's and their children from being active. just beofre each run of a unit test.

That way it will recreate any shared dependency each time and a unit test can't leak dependencies it added or changed into the next run.

One example of why this is good is for moto when mocking dynamodb in boto3 client. Can use dependency to ensure that we get a new dynamodb shared dependency for boto each time a unit test executes (which helps with moto, it needs to be active when a dependency is allocated/used).

This is exactly what we want for each unit test run, to have a blank-slate for all the vairous dependencies.

If a particulre set of unit-tests need to have specific dependcies, you can use fixtures to modify/add various dependcies as needed for each indivirual unit-test function run.

When the application runs for real though, we do generally want to use the dependencies in a shared fashion. So normally we only allocate a new blank-root @XContext(parent=None) either at the start of a normal application run, or during a unit-test.

var cloudformation : Any

The type of the None singleton.

var cloudwatch : Any

The type of the None singleton.

var dynamodb : Any

The type of the None singleton.

var ec2 : Any

The type of the None singleton.

var glacier : Any

The type of the None singleton.

var iam : Any

The type of the None singleton.

var ns : Any

The type of the None singleton.

var opsworks : Any

The type of the None singleton.

var s3 : Any

The type of the None singleton.

var sqs : Any

The type of the None singleton.

Static methods

def __init_subclass__(thread_sharable: bool | DefaultType = Default,
remove_between_unittests: bool | DefaultType = Default,
attributes_to_skip_while_copying: Iterable[str] | None = Default,
**kwargs)

Inherited from: Dependency.__init_subclass__

Args

remove_between_unittests
If False (default): Dependency will be removed from global context before/after as each individual …
def grab() ‑> ~T

Inherited from: Dependency.grab

Gets a potentially shared dependency from the current udpend.context.XContext

def proxy() ‑> ~R

Inherited from: Dependency.proxy

Returns a proxy-object, that when and attribute is asked for, it will proxy it to the current object of cls

def proxy_attribute(attribute_name: str) ‑> Any

Inherited from: Dependency.proxy_attribute

Returns a proxy-object, that when and attribute is asked for, it will proxy it to the current attribute value on the current object of cls

Instance variables

var obj : ClassVar[Self]

Inherited from: Dependency.obj

class property/attribute that will return the current dependency for the subclass it's asked on by calling Dependency.grab, passing no extra …

Methods

def __call__(self, func)

Inherited from: Dependency.__call__

This makes Resource subclasses have an ability to be used as function decorators by default unless this method is overriden to provide some other …

def __copy__(self)

Inherited from: Dependency.__copy__

Basic shallow copy protection (I am wondering if I should just remove this default copy code) …

class BotoSession (*,
reset_session_when_activated=False,
aws_access_key_id: str | None = None,
aws_secret_access_key: str | None = None,
aws_session_token: str | None = None,
region_name: str | None = None,
botocore_session: botocore.session.Session | None = None,
profile_name: str | None = None,
**session_kwargs)
Expand source code
class BotoSession(Dependency):
    """
    You can use this as an easy way to get a shared boto-session for the current thread.

    Right now only used with `_Loader` subclasses such as `BotoClients` and `BotoResources`.

    Boto Sessions are NOT thread-safe.
    When user is not using a session to create a client/resource,
    boto3 uses an internal/default session instead which is not thread-safe.

    - Or the docs for boto about this:
        - https://boto3.amazonaws.com/v1/documentation/api/latest/guide/session.html
    - For various examples see issue where people talk about it:
        - https://github.com/boto/botocore/issues/1246
    """

    @property
    def session(self) -> boto3.Session:
        if session := self._session:
            return session
        session = boto3.Session(**self._session_kwargs)
        self._session = session
        return session

    def __init__(
            self, *,
            reset_session_when_activated=False,
            aws_access_key_id: Optional[str] = None,
            aws_secret_access_key: Optional[str] = None,
            aws_session_token: Optional[str] = None,
            region_name: Optional[str] = None,
            botocore_session: Optional[Session] = None,
            profile_name: Optional[str] = None,
            **session_kwargs
    ):
        """

        Args:
            reset_session_when_activated: If True: when self is activated
                (ie: made the current resource/dependency)
                will automatically call `BotoSession.reset_session()`, and therefore next time
                `BotoSession.session` is asked for will lazily allocate new boto Session.
                This is useful for unit-tests, where you really do want to create a new
                session/connection each time the unit-test is called if you use
                `BotoSession` as a decorator to a unit-testing method.

                If False (default): will keep any session that has been previously/lazily created.
                This keeps the connections around for you; hence why it's the default option.

            aws_access_key_id (str):  access key ID
            aws_secret_access_key (str): AWS secret access key
            aws_session_token (str): AWS temporary session token
            region_name (str): Default region when creating new connections
            botocore_session (botocore.session.Session): Use this Botocore session instead of
                creating a new default one.
            profile_name (str): The name of a profile to use. If not given, then the default
                profile is used.
            **session_kwargs: Pass additional args for boto Session here
                (for additional args that boto3 might add in the future).
        """
        # Easily grab all boto args passed into us...
        args = {k: v for k, v in locals().items() if v is not None}
        args.pop('self', None)
        args.pop('reset_session_when_activated', None)
        args.pop('session_kwargs', None)

        # Remember args...
        self.reset_session_when_activated = reset_session_when_activated
        self._session_kwargs = {**args, **session_kwargs}
        self._boto_obj_store = {}

    def context_resource_for_copy(
            self, *, current_context: XContext, copied_context: XContext
    ) -> 'BotoSession':
        if self.reset_session_when_activated:
            self.reset_session()
        return self

    @property
    def session_kwargs(self) -> Dict[str, Any]:
        return self._session_kwargs.copy()

    @session_kwargs.setter
    def session_kwargs(self, value: Dict[str, Any]):
        self._session_kwargs = {**value}
        self.reset_session()

    def reset_session(self):
        # We will lazily create session and their associated boto-objs in the future as needed.
        self._session = None
        self._boto_obj_store = {}

    _session: Optional[boto3.Session] = None
    _session_kwargs: dict
    _boto_obj_store: dict

    def _boto_obj_for_dependency(
            self,
            dependency: '_BaseBotoClientOrResource',
            constructor: Callable,
            force_create: bool = False
    ):
        if not force_create and (boto_obj := self._boto_obj_store.get(dependency)):
            return boto_obj

        boto_obj = constructor()
        self._boto_obj_store[dependency] = boto_obj
        return boto_obj

    def _reset_boto_obj_for_dependency(self, dependency: '_BaseBotoClientOrResource'):
        self._boto_obj_store.pop(dependency, None)

You can use this as an easy way to get a shared boto-session for the current thread.

Right now only used with _Loader subclasses such as BotoClients and BotoResources.

Boto Sessions are NOT thread-safe. When user is not using a session to create a client/resource, boto3 uses an internal/default session instead which is not thread-safe.

Args

reset_session_when_activated

If True: when self is activated (ie: made the current resource/dependency) will automatically call BotoSession.reset_session(), and therefore next time BotoSession.session is asked for will lazily allocate new boto Session. This is useful for unit-tests, where you really do want to create a new session/connection each time the unit-test is called if you use BotoSession as a decorator to a unit-testing method.

If False (default): will keep any session that has been previously/lazily created. This keeps the connections around for you; hence why it's the default option.

aws_access_key_id : str
access key ID
aws_secret_access_key : str
AWS secret access key
aws_session_token : str
AWS temporary session token
region_name : str
Default region when creating new connections
botocore_session : botocore.session.Session
Use this Botocore session instead of creating a new default one.
profile_name : str
The name of a profile to use. If not given, then the default profile is used.
**session_kwargs
Pass additional args for boto Session here (for additional args that boto3 might add in the future).

Ancestors

Static methods

def __init_subclass__(thread_sharable: bool | DefaultType = Default,
remove_between_unittests: bool | DefaultType = Default,
attributes_to_skip_while_copying: Iterable[str] | None = Default,
**kwargs)

Inherited from: Dependency.__init_subclass__

Args

remove_between_unittests
If False (default): Dependency will be removed from global context before/after as each individual …
def grab() ‑> ~T

Inherited from: Dependency.grab

Gets a potentially shared dependency from the current udpend.context.XContext

def proxy() ‑> ~R

Inherited from: Dependency.proxy

Returns a proxy-object, that when and attribute is asked for, it will proxy it to the current object of cls

def proxy_attribute(attribute_name: str) ‑> Any

Inherited from: Dependency.proxy_attribute

Returns a proxy-object, that when and attribute is asked for, it will proxy it to the current attribute value on the current object of cls

Instance variables

var obj : ClassVar[Self]

Inherited from: Dependency.obj

class property/attribute that will return the current dependency for the subclass it's asked on by calling Dependency.grab, passing no extra …

prop session : boto3.session.Session
Expand source code
@property
def session(self) -> boto3.Session:
    if session := self._session:
        return session
    session = boto3.Session(**self._session_kwargs)
    self._session = session
    return session
prop session_kwargs : Dict[str, Any]
Expand source code
@property
def session_kwargs(self) -> Dict[str, Any]:
    return self._session_kwargs.copy()

Methods

def __call__(self, func)

Inherited from: Dependency.__call__

This makes Resource subclasses have an ability to be used as function decorators by default unless this method is overriden to provide some other …

def __copy__(self)

Inherited from: Dependency.__copy__

Basic shallow copy protection (I am wondering if I should just remove this default copy code) …

def context_resource_for_copy(self,
*,
current_context: XContext,
copied_context: XContext) ‑> BotoSession
Expand source code
def context_resource_for_copy(
        self, *, current_context: XContext, copied_context: XContext
) -> 'BotoSession':
    if self.reset_session_when_activated:
        self.reset_session()
    return self
def reset_session(self)
Expand source code
def reset_session(self):
    # We will lazily create session and their associated boto-objs in the future as needed.
    self._session = None
    self._boto_obj_store = {}