Repository files navigation

Mu

noxpypi

AWS Lambda support for Python projects.

Project Setup

To use mu, a project needs a pyproject.toml and either

  1. a mu.toml in the same directory (takes precedence); or
  2. tools.mu sections in the pyproject.toml

It also needs

  • Dockerfile
  • compose.yaml (or docker-compose.yaml if you insist)
  • An entry point in the app for the lambda events

An example application with these required elements can be found at: mu_hello

Usage: Local

Let's demonstrate usage with mu_hello. Assuming you have copied that source locally and are in the directory:

$ mu build
$ docker compose up mu-hello
# Watch current shell for log output and, in a new shell, run:
$ mu invoke --local

That command should have output like:

{'context': {'aws_request_id': '83fd7a58-5f6d-45e1-8092-b509c4f60898',
'function_name': 'test_function',
'function_version': '$LATEST',
'invoked_function_arn': 'arn:aws:lambda:us-east-1:012345678912:function:test_function',
'log_group_name': '/aws/lambda/Functions',
'log_stream_name': '$LATEST',
'memory_limit_in_mb': '3008',
'remaining_time': 299967},
'error': None,
'event': {'action-args': [], 'do-action': 'diagnostics'}}

And the first shell should have output like:

11 Jun 2024 19:28:28,809 [INFO] (rapid) INIT START(type: on-demand, phase: init)
...
11 Jun 2024 19:28:28,843 [INFO] (rapid) INVOKE RTDONE(status: success, produced bytes: 0, duration: 0.724000ms)

Now invoke the hello command:

$ mu invoke --local hello
'Hello World from mu_hello'# with arguments
$ mu invoke --local hello 'Capt. Picard''Hello Capt. Picard from mu_Hello'# call a Click command
$ mu invoke --local cli
47
# And you should see the following in the docker shell'Hello Alpha Quadrant from mu_Hello'

Usage: AWS

This is assuming you are (still) in the mu_hello directory and have AWS auth setup. aws sts get-caller-identity should be working.

Verify AWS auth:
$ mu auth-check
Account: 429812345678
Region: us-east-2
Organization owner: you@example.com

Note that mu has the concept of an "environment" which is used when naming objects to support provision and deployment for beta, prod, etc. There is a default environment that is part of the mu config and defaults to you.your-host.

# Ensure IAM and ECR infra. is in place for the enterprise environment
$ mu provision enterprise
info Role created: starfleet-mu-hello-lambda-enterprise
info Policy created: starfleet-mu-hello-lambda-enterprise-logs
info Policy created: starfleet-mu-hello-lambda-enterprise-ecr-repo
info Repository created: starfleet-mu-hello-enterprise
info Waiting 0.1s for role to be ready
info Waiting 0.25s for role to be ready
...[snip]...
info Provision finished for env: enterprise
# Build and push image, setup aws lambda
$ mu deploy --build enterprise
info docker compose build --pull
[+] Building 0.3s (10/10)
...[snip docker output]...
info Tagged, pushing...
info Tagged and pushed: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise mu-hello-2024-06-11T21.31.09
info Deploying: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise:mu-hello-2024-06-11T21.31.09
info Lambda functioncreated: starfleet-mu-hello-handler-enterprise
info Function arn: arn:aws:lambda:us-east-2:429829037495:function:starfleet-mu-hello-handler-enterprise
info Waiting for lambda to be updated: starfleet-mu-hello-handler-enterprise
$ mu invoke --env enterprise
{'context': {'aws_request_id': 'cc44e34f-b7f1-4f2a-a314-e4dd2513b229'
...[snip]...

Usage: Async Tasks

Async task workers without a broker/queue:

fromflaskimportFlaskimportmuapp=Flask(__name__)
@mu.taskdefping_task(a, *, b):
print('ping_task()', a, b)
@app.route('/ping')defping():
# ping_task() will be called through async lambda invokationping_task.invoke(1, b=2)
return'ok'@mu.task(lambda_func='this-app-bigger-lambda')defcrunch_big_numbers(a, b, c):
""" You can change the lambda name but it still needs to be this app. """print('crunch_big_numbers()', a, b, c)

Be mindeful of:

Dev

Copier Template

Project structure and tooling mostly derives from the Coppy, see its documentation for context and additional instructions.

This project can be updated from the upstream repo, see Updating a Project.

Project Setup

From zero to hero (passing tests that is):

  1. Ensure host dependencies are installed

  2. Sync project virtualenv w/ lock file:

    uv sync

  3. Configure pre-commit:

    pre-commit install

  4. Run tests w/ nox or pytest but see notes just below first.

Testing

Credentials

This project has a lot of integration tests that use live AWS. You SHOULD have a dedicated AWS account for mu testing.

An env-config config is present which will use aws-vault and a "mu-test" profile to load AWS creds. But, you can use any method you prefer to setup credentials for boto3.

Running tests

  • Setup AWS credentials (see notes above)
  • Add mise.local.toml to override MU_TEST_ACCT_ID
  • nox or pytest
  • Some integration tests are marked as such (other integration tests should get marked)
    • pytest -m 'not integration' ...` will skip integration tests
    • pytest -m 'integration' ...` will target integration tests

Versions

Versions are date based. A bump action exists to help manage versions:

# Show current version
mise bump --show
# Bump version based on date, tag, and push:
mise bump
# See other options
mise bump -- --help

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Mu

noxpypi

AWS Lambda support for Python projects.

Project Setup

To use mu, a project needs a pyproject.toml and either

  1. a mu.toml in the same directory (takes precedence); or
  2. tools.mu sections in the pyproject.toml

It also needs

  • Dockerfile
  • compose.yaml (or docker-compose.yaml if you insist)
  • An entry point in the app for the lambda events

An example application with these required elements can be found at: mu_hello

Usage: Local

Let's demonstrate usage with mu_hello. Assuming you have copied that source locally and are in the directory:

$ mu build
$ docker compose up mu-hello
# Watch current shell for log output and, in a new shell, run:
$ mu invoke --local

That command should have output like:

{'context': {'aws_request_id': '83fd7a58-5f6d-45e1-8092-b509c4f60898',
'function_name': 'test_function',
'function_version': '$LATEST',
'invoked_function_arn': 'arn:aws:lambda:us-east-1:012345678912:function:test_function',
'log_group_name': '/aws/lambda/Functions',
'log_stream_name': '$LATEST',
'memory_limit_in_mb': '3008',
'remaining_time': 299967},
'error': None,
'event': {'action-args': [], 'do-action': 'diagnostics'}}

And the first shell should have output like:

11 Jun 2024 19:28:28,809 [INFO] (rapid) INIT START(type: on-demand, phase: init)
...
11 Jun 2024 19:28:28,843 [INFO] (rapid) INVOKE RTDONE(status: success, produced bytes: 0, duration: 0.724000ms)

Now invoke the hello command:

$ mu invoke --local hello
'Hello World from mu_hello'# with arguments
$ mu invoke --local hello 'Capt. Picard''Hello Capt. Picard from mu_Hello'# call a Click command
$ mu invoke --local cli
47
# And you should see the following in the docker shell'Hello Alpha Quadrant from mu_Hello'

Usage: AWS

This is assuming you are (still) in the mu_hello directory and have AWS auth setup. aws sts get-caller-identity should be working.

Verify AWS auth:
$ mu auth-check
Account: 429812345678
Region: us-east-2
Organization owner: you@example.com

Note that mu has the concept of an "environment" which is used when naming objects to support provision and deployment for beta, prod, etc. There is a default environment that is part of the mu config and defaults to you.your-host.

# Ensure IAM and ECR infra. is in place for the enterprise environment
$ mu provision enterprise
info Role created: starfleet-mu-hello-lambda-enterprise
info Policy created: starfleet-mu-hello-lambda-enterprise-logs
info Policy created: starfleet-mu-hello-lambda-enterprise-ecr-repo
info Repository created: starfleet-mu-hello-enterprise
info Waiting 0.1s for role to be ready
info Waiting 0.25s for role to be ready
...[snip]...
info Provision finished for env: enterprise
# Build and push image, setup aws lambda
$ mu deploy --build enterprise
info docker compose build --pull
[+] Building 0.3s (10/10)
...[snip docker output]...
info Tagged, pushing...
info Tagged and pushed: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise mu-hello-2024-06-11T21.31.09
info Deploying: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise:mu-hello-2024-06-11T21.31.09
info Lambda functioncreated: starfleet-mu-hello-handler-enterprise
info Function arn: arn:aws:lambda:us-east-2:429829037495:function:starfleet-mu-hello-handler-enterprise
info Waiting for lambda to be updated: starfleet-mu-hello-handler-enterprise
$ mu invoke --env enterprise
{'context': {'aws_request_id': 'cc44e34f-b7f1-4f2a-a314-e4dd2513b229'
...[snip]...

Usage: Async Tasks

Async task workers without a broker/queue:

fromflaskimportFlaskimportmuapp=Flask(__name__)
@mu.taskdefping_task(a, *, b):
print('ping_task()', a, b)
@app.route('/ping')defping():
# ping_task() will be called through async lambda invokationping_task.invoke(1, b=2)
return'ok'@mu.task(lambda_func='this-app-bigger-lambda')defcrunch_big_numbers(a, b, c):
""" You can change the lambda name but it still needs to be this app. """print('crunch_big_numbers()', a, b, c)

Be mindeful of:

Dev

Copier Template

Project structure and tooling mostly derives from the Coppy, see its documentation for context and additional instructions.

This project can be updated from the upstream repo, see Updating a Project.

Project Setup

From zero to hero (passing tests that is):

  1. Ensure host dependencies are installed

  2. Sync project virtualenv w/ lock file:

    uv sync

  3. Configure pre-commit:

    pre-commit install

  4. Run tests w/ nox or pytest but see notes just below first.

Testing

Credentials

This project has a lot of integration tests that use live AWS. You SHOULD have a dedicated AWS account for mu testing.

An env-config config is present which will use aws-vault and a "mu-test" profile to load AWS creds. But, you can use any method you prefer to setup credentials for boto3.

Running tests

  • Setup AWS credentials (see notes above)
  • Add mise.local.toml to override MU_TEST_ACCT_ID
  • nox or pytest
  • Some integration tests are marked as such (other integration tests should get marked)
    • pytest -m 'not integration' ...` will skip integration tests
    • pytest -m 'integration' ...` will target integration tests

Versions

Versions are date based. A bump action exists to help manage versions:

# Show current version
mise bump --show
# Bump version based on date, tag, and push:
mise bump
# See other options
mise bump -- --help

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Mu

noxpypi

AWS Lambda support for Python projects.

Project Setup

To use mu, a project needs a pyproject.toml and either

  1. a mu.toml in the same directory (takes precedence); or
  2. tools.mu sections in the pyproject.toml

It also needs

  • Dockerfile
  • compose.yaml (or docker-compose.yaml if you insist)
  • An entry point in the app for the lambda events

An example application with these required elements can be found at: mu_hello

Usage: Local

Let's demonstrate usage with mu_hello. Assuming you have copied that source locally and are in the directory:

$ mu build
$ docker compose up mu-hello
# Watch current shell for log output and, in a new shell, run:
$ mu invoke --local

That command should have output like:

{'context': {'aws_request_id': '83fd7a58-5f6d-45e1-8092-b509c4f60898',
'function_name': 'test_function',
'function_version': '$LATEST',
'invoked_function_arn': 'arn:aws:lambda:us-east-1:012345678912:function:test_function',
'log_group_name': '/aws/lambda/Functions',
'log_stream_name': '$LATEST',
'memory_limit_in_mb': '3008',
'remaining_time': 299967},
'error': None,
'event': {'action-args': [], 'do-action': 'diagnostics'}}

And the first shell should have output like:

11 Jun 2024 19:28:28,809 [INFO] (rapid) INIT START(type: on-demand, phase: init)
...
11 Jun 2024 19:28:28,843 [INFO] (rapid) INVOKE RTDONE(status: success, produced bytes: 0, duration: 0.724000ms)

Now invoke the hello command:

$ mu invoke --local hello
'Hello World from mu_hello'# with arguments
$ mu invoke --local hello 'Capt. Picard''Hello Capt. Picard from mu_Hello'# call a Click command
$ mu invoke --local cli
47
# And you should see the following in the docker shell'Hello Alpha Quadrant from mu_Hello'

Usage: AWS

This is assuming you are (still) in the mu_hello directory and have AWS auth setup. aws sts get-caller-identity should be working.

Verify AWS auth:
$ mu auth-check
Account: 429812345678
Region: us-east-2
Organization owner: you@example.com

Note that mu has the concept of an "environment" which is used when naming objects to support provision and deployment for beta, prod, etc. There is a default environment that is part of the mu config and defaults to you.your-host.

# Ensure IAM and ECR infra. is in place for the enterprise environment
$ mu provision enterprise
info Role created: starfleet-mu-hello-lambda-enterprise
info Policy created: starfleet-mu-hello-lambda-enterprise-logs
info Policy created: starfleet-mu-hello-lambda-enterprise-ecr-repo
info Repository created: starfleet-mu-hello-enterprise
info Waiting 0.1s for role to be ready
info Waiting 0.25s for role to be ready
...[snip]...
info Provision finished for env: enterprise
# Build and push image, setup aws lambda
$ mu deploy --build enterprise
info docker compose build --pull
[+] Building 0.3s (10/10)
...[snip docker output]...
info Tagged, pushing...
info Tagged and pushed: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise mu-hello-2024-06-11T21.31.09
info Deploying: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise:mu-hello-2024-06-11T21.31.09
info Lambda functioncreated: starfleet-mu-hello-handler-enterprise
info Function arn: arn:aws:lambda:us-east-2:429829037495:function:starfleet-mu-hello-handler-enterprise
info Waiting for lambda to be updated: starfleet-mu-hello-handler-enterprise
$ mu invoke --env enterprise
{'context': {'aws_request_id': 'cc44e34f-b7f1-4f2a-a314-e4dd2513b229'
...[snip]...

Usage: Async Tasks

Async task workers without a broker/queue:

fromflaskimportFlaskimportmuapp=Flask(__name__)
@mu.taskdefping_task(a, *, b):
print('ping_task()', a, b)
@app.route('/ping')defping():
# ping_task() will be called through async lambda invokationping_task.invoke(1, b=2)
return'ok'@mu.task(lambda_func='this-app-bigger-lambda')defcrunch_big_numbers(a, b, c):
""" You can change the lambda name but it still needs to be this app. """print('crunch_big_numbers()', a, b, c)

Be mindeful of:

Dev

Copier Template

Project structure and tooling mostly derives from the Coppy, see its documentation for context and additional instructions.

This project can be updated from the upstream repo, see Updating a Project.

Project Setup

From zero to hero (passing tests that is):

  1. Ensure host dependencies are installed

  2. Sync project virtualenv w/ lock file:

    uv sync

  3. Configure pre-commit:

    pre-commit install

  4. Run tests w/ nox or pytest but see notes just below first.

Testing

Credentials

This project has a lot of integration tests that use live AWS. You SHOULD have a dedicated AWS account for mu testing.

An env-config config is present which will use aws-vault and a "mu-test" profile to load AWS creds. But, you can use any method you prefer to setup credentials for boto3.

Running tests

  • Setup AWS credentials (see notes above)
  • Add mise.local.toml to override MU_TEST_ACCT_ID
  • nox or pytest
  • Some integration tests are marked as such (other integration tests should get marked)
    • pytest -m 'not integration' ...` will skip integration tests
    • pytest -m 'integration' ...` will target integration tests

Versions

Versions are date based. A bump action exists to help manage versions:

# Show current version
mise bump --show
# Bump version based on date, tag, and push:
mise bump
# See other options
mise bump -- --help

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Mu

noxpypi

AWS Lambda support for Python projects.

Project Setup

To use mu, a project needs a pyproject.toml and either

  1. a mu.toml in the same directory (takes precedence); or
  2. tools.mu sections in the pyproject.toml

It also needs

  • Dockerfile
  • compose.yaml (or docker-compose.yaml if you insist)
  • An entry point in the app for the lambda events

An example application with these required elements can be found at: mu_hello

Usage: Local

Let's demonstrate usage with mu_hello. Assuming you have copied that source locally and are in the directory:

$ mu build
$ docker compose up mu-hello
# Watch current shell for log output and, in a new shell, run:
$ mu invoke --local

That command should have output like:

{'context': {'aws_request_id': '83fd7a58-5f6d-45e1-8092-b509c4f60898',
'function_name': 'test_function',
'function_version': '$LATEST',
'invoked_function_arn': 'arn:aws:lambda:us-east-1:012345678912:function:test_function',
'log_group_name': '/aws/lambda/Functions',
'log_stream_name': '$LATEST',
'memory_limit_in_mb': '3008',
'remaining_time': 299967},
'error': None,
'event': {'action-args': [], 'do-action': 'diagnostics'}}

And the first shell should have output like:

11 Jun 2024 19:28:28,809 [INFO] (rapid) INIT START(type: on-demand, phase: init)
...
11 Jun 2024 19:28:28,843 [INFO] (rapid) INVOKE RTDONE(status: success, produced bytes: 0, duration: 0.724000ms)

Now invoke the hello command:

$ mu invoke --local hello
'Hello World from mu_hello'# with arguments
$ mu invoke --local hello 'Capt. Picard''Hello Capt. Picard from mu_Hello'# call a Click command
$ mu invoke --local cli
47
# And you should see the following in the docker shell'Hello Alpha Quadrant from mu_Hello'

Usage: AWS

This is assuming you are (still) in the mu_hello directory and have AWS auth setup. aws sts get-caller-identity should be working.

Verify AWS auth:
$ mu auth-check
Account: 429812345678
Region: us-east-2
Organization owner: you@example.com

Note that mu has the concept of an "environment" which is used when naming objects to support provision and deployment for beta, prod, etc. There is a default environment that is part of the mu config and defaults to you.your-host.

# Ensure IAM and ECR infra. is in place for the enterprise environment
$ mu provision enterprise
info Role created: starfleet-mu-hello-lambda-enterprise
info Policy created: starfleet-mu-hello-lambda-enterprise-logs
info Policy created: starfleet-mu-hello-lambda-enterprise-ecr-repo
info Repository created: starfleet-mu-hello-enterprise
info Waiting 0.1s for role to be ready
info Waiting 0.25s for role to be ready
...[snip]...
info Provision finished for env: enterprise
# Build and push image, setup aws lambda
$ mu deploy --build enterprise
info docker compose build --pull
[+] Building 0.3s (10/10)
...[snip docker output]...
info Tagged, pushing...
info Tagged and pushed: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise mu-hello-2024-06-11T21.31.09
info Deploying: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise:mu-hello-2024-06-11T21.31.09
info Lambda functioncreated: starfleet-mu-hello-handler-enterprise
info Function arn: arn:aws:lambda:us-east-2:429829037495:function:starfleet-mu-hello-handler-enterprise
info Waiting for lambda to be updated: starfleet-mu-hello-handler-enterprise
$ mu invoke --env enterprise
{'context': {'aws_request_id': 'cc44e34f-b7f1-4f2a-a314-e4dd2513b229'
...[snip]...

Usage: Async Tasks

Async task workers without a broker/queue:

fromflaskimportFlaskimportmuapp=Flask(__name__)
@mu.taskdefping_task(a, *, b):
print('ping_task()', a, b)
@app.route('/ping')defping():
# ping_task() will be called through async lambda invokationping_task.invoke(1, b=2)
return'ok'@mu.task(lambda_func='this-app-bigger-lambda')defcrunch_big_numbers(a, b, c):
""" You can change the lambda name but it still needs to be this app. """print('crunch_big_numbers()', a, b, c)

Be mindeful of:

Dev

Copier Template

Project structure and tooling mostly derives from the Coppy, see its documentation for context and additional instructions.

This project can be updated from the upstream repo, see Updating a Project.

Project Setup

From zero to hero (passing tests that is):

  1. Ensure host dependencies are installed

  2. Sync project virtualenv w/ lock file:

    uv sync

  3. Configure pre-commit:

    pre-commit install

  4. Run tests w/ nox or pytest but see notes just below first.

Testing

Credentials

This project has a lot of integration tests that use live AWS. You SHOULD have a dedicated AWS account for mu testing.

An env-config config is present which will use aws-vault and a "mu-test" profile to load AWS creds. But, you can use any method you prefer to setup credentials for boto3.

Running tests

  • Setup AWS credentials (see notes above)
  • Add mise.local.toml to override MU_TEST_ACCT_ID
  • nox or pytest
  • Some integration tests are marked as such (other integration tests should get marked)
    • pytest -m 'not integration' ...` will skip integration tests
    • pytest -m 'integration' ...` will target integration tests

Versions

Versions are date based. A bump action exists to help manage versions:

# Show current version
mise bump --show
# Bump version based on date, tag, and push:
mise bump
# See other options
mise bump -- --help

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Mu

noxpypi

AWS Lambda support for Python projects.

Project Setup

To use mu, a project needs a pyproject.toml and either

  1. a mu.toml in the same directory (takes precedence); or
  2. tools.mu sections in the pyproject.toml

It also needs

  • Dockerfile
  • compose.yaml (or docker-compose.yaml if you insist)
  • An entry point in the app for the lambda events

An example application with these required elements can be found at: mu_hello

Usage: Local

Let's demonstrate usage with mu_hello. Assuming you have copied that source locally and are in the directory:

$ mu build
$ docker compose up mu-hello
# Watch current shell for log output and, in a new shell, run:
$ mu invoke --local

That command should have output like:

{'context': {'aws_request_id': '83fd7a58-5f6d-45e1-8092-b509c4f60898',
'function_name': 'test_function',
'function_version': '$LATEST',
'invoked_function_arn': 'arn:aws:lambda:us-east-1:012345678912:function:test_function',
'log_group_name': '/aws/lambda/Functions',
'log_stream_name': '$LATEST',
'memory_limit_in_mb': '3008',
'remaining_time': 299967},
'error': None,
'event': {'action-args': [], 'do-action': 'diagnostics'}}

And the first shell should have output like:

11 Jun 2024 19:28:28,809 [INFO] (rapid) INIT START(type: on-demand, phase: init)
...
11 Jun 2024 19:28:28,843 [INFO] (rapid) INVOKE RTDONE(status: success, produced bytes: 0, duration: 0.724000ms)

Now invoke the hello command:

$ mu invoke --local hello
'Hello World from mu_hello'# with arguments
$ mu invoke --local hello 'Capt. Picard''Hello Capt. Picard from mu_Hello'# call a Click command
$ mu invoke --local cli
47
# And you should see the following in the docker shell'Hello Alpha Quadrant from mu_Hello'

Usage: AWS

This is assuming you are (still) in the mu_hello directory and have AWS auth setup. aws sts get-caller-identity should be working.

Verify AWS auth:
$ mu auth-check
Account: 429812345678
Region: us-east-2
Organization owner: you@example.com

Note that mu has the concept of an "environment" which is used when naming objects to support provision and deployment for beta, prod, etc. There is a default environment that is part of the mu config and defaults to you.your-host.

# Ensure IAM and ECR infra. is in place for the enterprise environment
$ mu provision enterprise
info Role created: starfleet-mu-hello-lambda-enterprise
info Policy created: starfleet-mu-hello-lambda-enterprise-logs
info Policy created: starfleet-mu-hello-lambda-enterprise-ecr-repo
info Repository created: starfleet-mu-hello-enterprise
info Waiting 0.1s for role to be ready
info Waiting 0.25s for role to be ready
...[snip]...
info Provision finished for env: enterprise
# Build and push image, setup aws lambda
$ mu deploy --build enterprise
info docker compose build --pull
[+] Building 0.3s (10/10)
...[snip docker output]...
info Tagged, pushing...
info Tagged and pushed: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise mu-hello-2024-06-11T21.31.09
info Deploying: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise:mu-hello-2024-06-11T21.31.09
info Lambda functioncreated: starfleet-mu-hello-handler-enterprise
info Function arn: arn:aws:lambda:us-east-2:429829037495:function:starfleet-mu-hello-handler-enterprise
info Waiting for lambda to be updated: starfleet-mu-hello-handler-enterprise
$ mu invoke --env enterprise
{'context': {'aws_request_id': 'cc44e34f-b7f1-4f2a-a314-e4dd2513b229'
...[snip]...

Usage: Async Tasks

Async task workers without a broker/queue:

fromflaskimportFlaskimportmuapp=Flask(__name__)
@mu.taskdefping_task(a, *, b):
print('ping_task()', a, b)
@app.route('/ping')defping():
# ping_task() will be called through async lambda invokationping_task.invoke(1, b=2)
return'ok'@mu.task(lambda_func='this-app-bigger-lambda')defcrunch_big_numbers(a, b, c):
""" You can change the lambda name but it still needs to be this app. """print('crunch_big_numbers()', a, b, c)

Be mindeful of:

Dev

Copier Template

Project structure and tooling mostly derives from the Coppy, see its documentation for context and additional instructions.

This project can be updated from the upstream repo, see Updating a Project.

Project Setup

From zero to hero (passing tests that is):

  1. Ensure host dependencies are installed

  2. Sync project virtualenv w/ lock file:

    uv sync

  3. Configure pre-commit:

    pre-commit install

  4. Run tests w/ nox or pytest but see notes just below first.

Testing

Credentials

This project has a lot of integration tests that use live AWS. You SHOULD have a dedicated AWS account for mu testing.

An env-config config is present which will use aws-vault and a "mu-test" profile to load AWS creds. But, you can use any method you prefer to setup credentials for boto3.

Running tests

  • Setup AWS credentials (see notes above)
  • Add mise.local.toml to override MU_TEST_ACCT_ID
  • nox or pytest
  • Some integration tests are marked as such (other integration tests should get marked)
    • pytest -m 'not integration' ...` will skip integration tests
    • pytest -m 'integration' ...` will target integration tests

Versions

Versions are date based. A bump action exists to help manage versions:

# Show current version
mise bump --show
# Bump version based on date, tag, and push:
mise bump
# See other options
mise bump -- --help

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Mu

noxpypi

AWS Lambda support for Python projects.

Project Setup

To use mu, a project needs a pyproject.toml and either

  1. a mu.toml in the same directory (takes precedence); or
  2. tools.mu sections in the pyproject.toml

It also needs

  • Dockerfile
  • compose.yaml (or docker-compose.yaml if you insist)
  • An entry point in the app for the lambda events

An example application with these required elements can be found at: mu_hello

Usage: Local

Let's demonstrate usage with mu_hello. Assuming you have copied that source locally and are in the directory:

$ mu build
$ docker compose up mu-hello
# Watch current shell for log output and, in a new shell, run:
$ mu invoke --local

That command should have output like:

{'context': {'aws_request_id': '83fd7a58-5f6d-45e1-8092-b509c4f60898',
'function_name': 'test_function',
'function_version': '$LATEST',
'invoked_function_arn': 'arn:aws:lambda:us-east-1:012345678912:function:test_function',
'log_group_name': '/aws/lambda/Functions',
'log_stream_name': '$LATEST',
'memory_limit_in_mb': '3008',
'remaining_time': 299967},
'error': None,
'event': {'action-args': [], 'do-action': 'diagnostics'}}

And the first shell should have output like:

11 Jun 2024 19:28:28,809 [INFO] (rapid) INIT START(type: on-demand, phase: init)
...
11 Jun 2024 19:28:28,843 [INFO] (rapid) INVOKE RTDONE(status: success, produced bytes: 0, duration: 0.724000ms)

Now invoke the hello command:

$ mu invoke --local hello
'Hello World from mu_hello'# with arguments
$ mu invoke --local hello 'Capt. Picard''Hello Capt. Picard from mu_Hello'# call a Click command
$ mu invoke --local cli
47
# And you should see the following in the docker shell'Hello Alpha Quadrant from mu_Hello'

Usage: AWS

This is assuming you are (still) in the mu_hello directory and have AWS auth setup. aws sts get-caller-identity should be working.

Verify AWS auth:
$ mu auth-check
Account: 429812345678
Region: us-east-2
Organization owner: you@example.com

Note that mu has the concept of an "environment" which is used when naming objects to support provision and deployment for beta, prod, etc. There is a default environment that is part of the mu config and defaults to you.your-host.

# Ensure IAM and ECR infra. is in place for the enterprise environment
$ mu provision enterprise
info Role created: starfleet-mu-hello-lambda-enterprise
info Policy created: starfleet-mu-hello-lambda-enterprise-logs
info Policy created: starfleet-mu-hello-lambda-enterprise-ecr-repo
info Repository created: starfleet-mu-hello-enterprise
info Waiting 0.1s for role to be ready
info Waiting 0.25s for role to be ready
...[snip]...
info Provision finished for env: enterprise
# Build and push image, setup aws lambda
$ mu deploy --build enterprise
info docker compose build --pull
[+] Building 0.3s (10/10)
...[snip docker output]...
info Tagged, pushing...
info Tagged and pushed: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise mu-hello-2024-06-11T21.31.09
info Deploying: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise:mu-hello-2024-06-11T21.31.09
info Lambda functioncreated: starfleet-mu-hello-handler-enterprise
info Function arn: arn:aws:lambda:us-east-2:429829037495:function:starfleet-mu-hello-handler-enterprise
info Waiting for lambda to be updated: starfleet-mu-hello-handler-enterprise
$ mu invoke --env enterprise
{'context': {'aws_request_id': 'cc44e34f-b7f1-4f2a-a314-e4dd2513b229'
...[snip]...

Usage: Async Tasks

Async task workers without a broker/queue:

fromflaskimportFlaskimportmuapp=Flask(__name__)
@mu.taskdefping_task(a, *, b):
print('ping_task()', a, b)
@app.route('/ping')defping():
# ping_task() will be called through async lambda invokationping_task.invoke(1, b=2)
return'ok'@mu.task(lambda_func='this-app-bigger-lambda')defcrunch_big_numbers(a, b, c):
""" You can change the lambda name but it still needs to be this app. """print('crunch_big_numbers()', a, b, c)

Be mindeful of:

Dev

Copier Template

Project structure and tooling mostly derives from the Coppy, see its documentation for context and additional instructions.

This project can be updated from the upstream repo, see Updating a Project.

Project Setup

From zero to hero (passing tests that is):

  1. Ensure host dependencies are installed

  2. Sync project virtualenv w/ lock file:

    uv sync

  3. Configure pre-commit:

    pre-commit install

  4. Run tests w/ nox or pytest but see notes just below first.

Testing

Credentials

This project has a lot of integration tests that use live AWS. You SHOULD have a dedicated AWS account for mu testing.

An env-config config is present which will use aws-vault and a "mu-test" profile to load AWS creds. But, you can use any method you prefer to setup credentials for boto3.

Running tests

  • Setup AWS credentials (see notes above)
  • Add mise.local.toml to override MU_TEST_ACCT_ID
  • nox or pytest
  • Some integration tests are marked as such (other integration tests should get marked)
    • pytest -m 'not integration' ...` will skip integration tests
    • pytest -m 'integration' ...` will target integration tests

Versions

Versions are date based. A bump action exists to help manage versions:

# Show current version
mise bump --show
# Bump version based on date, tag, and push:
mise bump
# See other options
mise bump -- --help

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Mu

noxpypi

AWS Lambda support for Python projects.

Project Setup

To use mu, a project needs a pyproject.toml and either

  1. a mu.toml in the same directory (takes precedence); or
  2. tools.mu sections in the pyproject.toml

It also needs

  • Dockerfile
  • compose.yaml (or docker-compose.yaml if you insist)
  • An entry point in the app for the lambda events

An example application with these required elements can be found at: mu_hello

Usage: Local

Let's demonstrate usage with mu_hello. Assuming you have copied that source locally and are in the directory:

$ mu build
$ docker compose up mu-hello
# Watch current shell for log output and, in a new shell, run:
$ mu invoke --local

That command should have output like:

{'context': {'aws_request_id': '83fd7a58-5f6d-45e1-8092-b509c4f60898',
'function_name': 'test_function',
'function_version': '$LATEST',
'invoked_function_arn': 'arn:aws:lambda:us-east-1:012345678912:function:test_function',
'log_group_name': '/aws/lambda/Functions',
'log_stream_name': '$LATEST',
'memory_limit_in_mb': '3008',
'remaining_time': 299967},
'error': None,
'event': {'action-args': [], 'do-action': 'diagnostics'}}

And the first shell should have output like:

11 Jun 2024 19:28:28,809 [INFO] (rapid) INIT START(type: on-demand, phase: init)
...
11 Jun 2024 19:28:28,843 [INFO] (rapid) INVOKE RTDONE(status: success, produced bytes: 0, duration: 0.724000ms)

Now invoke the hello command:

$ mu invoke --local hello
'Hello World from mu_hello'# with arguments
$ mu invoke --local hello 'Capt. Picard''Hello Capt. Picard from mu_Hello'# call a Click command
$ mu invoke --local cli
47
# And you should see the following in the docker shell'Hello Alpha Quadrant from mu_Hello'

Usage: AWS

This is assuming you are (still) in the mu_hello directory and have AWS auth setup. aws sts get-caller-identity should be working.

Verify AWS auth:
$ mu auth-check
Account: 429812345678
Region: us-east-2
Organization owner: you@example.com

Note that mu has the concept of an "environment" which is used when naming objects to support provision and deployment for beta, prod, etc. There is a default environment that is part of the mu config and defaults to you.your-host.

# Ensure IAM and ECR infra. is in place for the enterprise environment
$ mu provision enterprise
info Role created: starfleet-mu-hello-lambda-enterprise
info Policy created: starfleet-mu-hello-lambda-enterprise-logs
info Policy created: starfleet-mu-hello-lambda-enterprise-ecr-repo
info Repository created: starfleet-mu-hello-enterprise
info Waiting 0.1s for role to be ready
info Waiting 0.25s for role to be ready
...[snip]...
info Provision finished for env: enterprise
# Build and push image, setup aws lambda
$ mu deploy --build enterprise
info docker compose build --pull
[+] Building 0.3s (10/10)
...[snip docker output]...
info Tagged, pushing...
info Tagged and pushed: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise mu-hello-2024-06-11T21.31.09
info Deploying: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise:mu-hello-2024-06-11T21.31.09
info Lambda functioncreated: starfleet-mu-hello-handler-enterprise
info Function arn: arn:aws:lambda:us-east-2:429829037495:function:starfleet-mu-hello-handler-enterprise
info Waiting for lambda to be updated: starfleet-mu-hello-handler-enterprise
$ mu invoke --env enterprise
{'context': {'aws_request_id': 'cc44e34f-b7f1-4f2a-a314-e4dd2513b229'
...[snip]...

Usage: Async Tasks

Async task workers without a broker/queue:

fromflaskimportFlaskimportmuapp=Flask(__name__)
@mu.taskdefping_task(a, *, b):
print('ping_task()', a, b)
@app.route('/ping')defping():
# ping_task() will be called through async lambda invokationping_task.invoke(1, b=2)
return'ok'@mu.task(lambda_func='this-app-bigger-lambda')defcrunch_big_numbers(a, b, c):
""" You can change the lambda name but it still needs to be this app. """print('crunch_big_numbers()', a, b, c)

Be mindeful of:

Dev

Copier Template

Project structure and tooling mostly derives from the Coppy, see its documentation for context and additional instructions.

This project can be updated from the upstream repo, see Updating a Project.

Project Setup

From zero to hero (passing tests that is):

  1. Ensure host dependencies are installed

  2. Sync project virtualenv w/ lock file:

    uv sync

  3. Configure pre-commit:

    pre-commit install

  4. Run tests w/ nox or pytest but see notes just below first.

Testing

Credentials

This project has a lot of integration tests that use live AWS. You SHOULD have a dedicated AWS account for mu testing.

An env-config config is present which will use aws-vault and a "mu-test" profile to load AWS creds. But, you can use any method you prefer to setup credentials for boto3.

Running tests

  • Setup AWS credentials (see notes above)
  • Add mise.local.toml to override MU_TEST_ACCT_ID
  • nox or pytest
  • Some integration tests are marked as such (other integration tests should get marked)
    • pytest -m 'not integration' ...` will skip integration tests
    • pytest -m 'integration' ...` will target integration tests

Versions

Versions are date based. A bump action exists to help manage versions:

# Show current version
mise bump --show
# Bump version based on date, tag, and push:
mise bump
# See other options
mise bump -- --help

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Mu

noxpypi

AWS Lambda support for Python projects.

Project Setup

To use mu, a project needs a pyproject.toml and either

  1. a mu.toml in the same directory (takes precedence); or
  2. tools.mu sections in the pyproject.toml

It also needs

  • Dockerfile
  • compose.yaml (or docker-compose.yaml if you insist)
  • An entry point in the app for the lambda events

An example application with these required elements can be found at: mu_hello

Usage: Local

Let's demonstrate usage with mu_hello. Assuming you have copied that source locally and are in the directory:

$ mu build
$ docker compose up mu-hello
# Watch current shell for log output and, in a new shell, run:
$ mu invoke --local

That command should have output like:

{'context': {'aws_request_id': '83fd7a58-5f6d-45e1-8092-b509c4f60898',
'function_name': 'test_function',
'function_version': '$LATEST',
'invoked_function_arn': 'arn:aws:lambda:us-east-1:012345678912:function:test_function',
'log_group_name': '/aws/lambda/Functions',
'log_stream_name': '$LATEST',
'memory_limit_in_mb': '3008',
'remaining_time': 299967},
'error': None,
'event': {'action-args': [], 'do-action': 'diagnostics'}}

And the first shell should have output like:

11 Jun 2024 19:28:28,809 [INFO] (rapid) INIT START(type: on-demand, phase: init)
...
11 Jun 2024 19:28:28,843 [INFO] (rapid) INVOKE RTDONE(status: success, produced bytes: 0, duration: 0.724000ms)

Now invoke the hello command:

$ mu invoke --local hello
'Hello World from mu_hello'# with arguments
$ mu invoke --local hello 'Capt. Picard''Hello Capt. Picard from mu_Hello'# call a Click command
$ mu invoke --local cli
47
# And you should see the following in the docker shell'Hello Alpha Quadrant from mu_Hello'

Usage: AWS

This is assuming you are (still) in the mu_hello directory and have AWS auth setup. aws sts get-caller-identity should be working.

Verify AWS auth:
$ mu auth-check
Account: 429812345678
Region: us-east-2
Organization owner: you@example.com

Note that mu has the concept of an "environment" which is used when naming objects to support provision and deployment for beta, prod, etc. There is a default environment that is part of the mu config and defaults to you.your-host.

# Ensure IAM and ECR infra. is in place for the enterprise environment
$ mu provision enterprise
info Role created: starfleet-mu-hello-lambda-enterprise
info Policy created: starfleet-mu-hello-lambda-enterprise-logs
info Policy created: starfleet-mu-hello-lambda-enterprise-ecr-repo
info Repository created: starfleet-mu-hello-enterprise
info Waiting 0.1s for role to be ready
info Waiting 0.25s for role to be ready
...[snip]...
info Provision finished for env: enterprise
# Build and push image, setup aws lambda
$ mu deploy --build enterprise
info docker compose build --pull
[+] Building 0.3s (10/10)
...[snip docker output]...
info Tagged, pushing...
info Tagged and pushed: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise mu-hello-2024-06-11T21.31.09
info Deploying: 429829037495.dkr.ecr.us-east-2.amazonaws.com/starfleet-mu-hello-enterprise:mu-hello-2024-06-11T21.31.09
info Lambda functioncreated: starfleet-mu-hello-handler-enterprise
info Function arn: arn:aws:lambda:us-east-2:429829037495:function:starfleet-mu-hello-handler-enterprise
info Waiting for lambda to be updated: starfleet-mu-hello-handler-enterprise
$ mu invoke --env enterprise
{'context': {'aws_request_id': 'cc44e34f-b7f1-4f2a-a314-e4dd2513b229'
...[snip]...

Usage: Async Tasks

Async task workers without a broker/queue:

fromflaskimportFlaskimportmuapp=Flask(__name__)
@mu.taskdefping_task(a, *, b):
print('ping_task()', a, b)
@app.route('/ping')defping():
# ping_task() will be called through async lambda invokationping_task.invoke(1, b=2)
return'ok'@mu.task(lambda_func='this-app-bigger-lambda')defcrunch_big_numbers(a, b, c):
""" You can change the lambda name but it still needs to be this app. """print('crunch_big_numbers()', a, b, c)

Be mindeful of:

Dev

Copier Template

Project structure and tooling mostly derives from the Coppy, see its documentation for context and additional instructions.

This project can be updated from the upstream repo, see Updating a Project.

Project Setup

From zero to hero (passing tests that is):

  1. Ensure host dependencies are installed

  2. Sync project virtualenv w/ lock file:

    uv sync

  3. Configure pre-commit:

    pre-commit install

  4. Run tests w/ nox or pytest but see notes just below first.

Testing

Credentials

This project has a lot of integration tests that use live AWS. You SHOULD have a dedicated AWS account for mu testing.

An env-config config is present which will use aws-vault and a "mu-test" profile to load AWS creds. But, you can use any method you prefer to setup credentials for boto3.

Running tests

  • Setup AWS credentials (see notes above)
  • Add mise.local.toml to override MU_TEST_ACCT_ID
  • nox or pytest
  • Some integration tests are marked as such (other integration tests should get marked)
    • pytest -m 'not integration' ...` will skip integration tests
    • pytest -m 'integration' ...` will target integration tests

Versions

Versions are date based. A bump action exists to help manage versions:

# Show current version
mise bump --show
# Bump version based on date, tag, and push:
mise bump
# See other options
mise bump -- --help

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages