Skip to content

Instantly share code, notes, and snippets.

Avatar

Melvin Koh melvinkcx

View GitHub Profile
@melvinkcx
melvinkcx / craft_lambda_trigger_event.py
Last active Nov 20, 2020
Crafting CloudWatch Logs Lambda Event
View craft_lambda_trigger_event.py
import base64
import gzip
import json
event = {
"logGroup": "/ecs/melvin-dev",
"logStream": "ecs/melvin-dev/XXXXXXXXXX",
"owner": 100000000000,
"logEvents": [{
@melvinkcx
melvinkcx / main.tf
Last active Sep 18, 2020
Terraform Provisioner: Wait For ECS To Register With LB Before Destroying
View main.tf
# Ref: https://github.com/terraform-providers/terraform-provider-aws/pull/3485#issuecomment-397918310
resource "aws_ecs_service" "web" {
name = "web_service_${var.environment}_${replace(timestamp(), ":", "-")}"
cluster = aws_ecs_cluster.web.id
task_definition = aws_ecs_task_definition.web.arn
desired_count = 1
force_new_deployment = true
@melvinkcx
melvinkcx / celery_app.py
Created Sep 17, 2020
Configure Celery To Write Logs To Papertrail
View celery_app.py
import logging
import os
from celery import Celery
from celery.schedules import crontab
from celery.signals import after_setup_logger, after_setup_task_logger
from django.conf import settings
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
@melvinkcx
melvinkcx / container_definitions.tmpl
Created Sep 16, 2020
ECS Task Definition With SSM Params Injected Into `container_definition.tmpl`
View container_definitions.tmpl
[
{
"name": "your_app",
"image": "${image_repo_arn}:${image_tag}",
"essential": true,
"memoryReservation": 300,
"portMappings": [
{
"hostPort": 80,
"containerPort": 8000,
@melvinkcx
melvinkcx / scraper.py
Created Aug 18, 2020
Run Scrapy Crawler In A Script (Without Project)
View scraper.py
import logging
from scrapy import signals
from scrapy.crawler import Crawler
from twisted.internet import reactor
from xxx.scraper.spiders import XXXSpider
logger = logging.getLogger(__name__)
@melvinkcx
melvinkcx / global_errors_in_react.md
Last active Jul 1, 2020
Handling Errors Globally In React
View global_errors_in_react.md

Handling Global Errors In React

My Approach: React Context with a custom useError hook

Even though React provides Error Boundaries API, it is not a good candidate, nor is relevant for handling GraphQL query errors.

useError custom hook

import { useState, useCallback } from 'react';
@melvinkcx
melvinkcx / assertion.py
Created May 20, 2020
Testing Django Signals Emission
View assertion.py
from collections import Mapping
from dataclasses import dataclass
from typing import Any, Tuple
@dataclass()
class SignalHandlerContext:
sender: Any
args: Tuple[Any]
kwargs: Mapping
@melvinkcx
melvinkcx / interactive_docker.md
Created Jan 10, 2020
Docker Compose Interactive Mode for Debugging
View interactive_docker.md

Interactive Docker Container for Debugging with Compose

In order for PDB to work in a Docker container, you can use

docker run -it <image_name>

For Docker Compose, add two lines stdin_open: true and tty: true into the service of your docker-compose.yml:

@melvinkcx
melvinkcx / profiler_decorator.py
Last active Dec 23, 2019
A decorator to run profiler in Python
View profiler_decorator.py
"""
with Python 3.8, you can use context manager with cProfile.Profile()
"""
def profile(func, filename="stats"):
def wrapper(*args, **kwargs):
import cProfile, pstats, io
from pstats import SortKey
pr = cProfile.Profile()
pr.enable()
@melvinkcx
melvinkcx / index.js
Created Dec 22, 2019
Yielding Python Generator from JS in PyWebView: A Dummy Example
View index.js
async *genLogs() {
while (true) {
yield await window.pywebview.api.gen_logs();
}
}
const g = genLogs();
(await g.next()).value // 1
(await g.next()).value // 2
You can’t perform that action at this time.