Custom Request Validation with ozzo-validation in Go
Custom validation in Echo using ozzo-validation makes input handling much cleaner and more structured. Instead of manually checking each field, you can define validation rules declaratively. Let鈥檚 say we need to validate a form submission where each field has attributes like label, type, and is_required. package form_requests import ( "fmt" "regexp" validation "github.com/go-ozzo/ozzo-validation/v4" "github.com/labstack/echo/v4" ) // FieldRequest defines a single form field type FieldRequest struct { Label string `json:"label"` Type string `json:"type"` IsRequired bool `json:"is_required"` } // CreateFormFieldsRequest wraps multiple fields type CreateFormFieldsRequest struct { Fields []FieldRequest `json:"fields"` } // BindAndValidate binds JSON data and runs validation func (r *CreateFormFieldsRequest) BindAndValidate(c echo.Context) []string { if err := c.Bind(r); err != nil { return []string{"Invalid request payload"} } err := validation.ValidateStruct(r, validation.Field(&r.Fields, validation.Required.Error("Fields array is required"), validation.Each( validation.By(validateField), )), ) return extractValidationErrors(err) } // validateField ensures each field meets the required rules func validateField(value interface{}) error { field, ok := value.(FieldRequest) if !ok { return fmt.Errorf("invalid field format") } return validation.ValidateStruct(&field, validation.Field(&field.Label, validation.Required.Error("Label is required"), validation.Length(3, 50).Error("Label must be between 3 and 50 characters"), validation.Match(regexp.MustCompile(`^[a-zA-Z0-9_-]+$`)).Error("Label can only contain letters, numbers, underscores, and dashes"), ), validation.Field(&field.Type, validation.Required.Error("Type is required"), validation.In("text", "number", "email", "date", "checkbox").Error("Invalid field type"), ), validation.Field(&field.IsRequired, validation.Required.Error("IsRequired is required")), ) } // extractValidationErrors formats errors into a slice of strings func extractValidationErrors(err error) []string { if err == nil { return nil } var errors []string if ve, ok := err.(validation.Errors); ok { for _, e := range ve { errors = append(errors, e.Error()) } } return errors } Declarative Validation: Instead of manually checking fields, ozzo-validation provides a clean way to define rules. Custom Validation Function: validateField() ensures each field meets the required format and constraints. Consistent Error Handling: extractValidationErrors() collects and formats validation errors into a slice for easier debugging and response handling.
Group Similar Routes in Go Echo
Using Echo groups is a great way to organize routes, especially when dealing with versioning, middleware, or related endpoints. Instead of cluttering the main file with multiple routes, you can logically group them. package main import ( "net/http" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" ) func main() { e := echo.New() // Global middleware e.Use(middleware.Logger()) e.Use(middleware.Recover()) // API versioning v1 := e.Group("/api/v1") // Group for user-related routes users := v1.Group("/users") users.GET("", getUsers) // GET /api/v1/users users.POST("", createUser) // POST /api/v1/users users.GET("/:id", getUserByID) // GET /api/v1/users/:id // Group for admin routes with middleware admin := v1.Group("/admin", adminMiddleware) admin.GET("/dashboard", adminDashboard) // GET /api/v1/admin/dashboard e.Logger.Fatal(e.Start(":8080")) } // Handlers func getUsers(c echo.Context) error { return c.JSON(http.StatusOK, map[string]string{"message": "List of users"}) } func createUser(c echo.Context) error { return c.JSON(http.StatusCreated, map[string]string{"message": "User created"}) } func getUserByID(c echo.Context) error { id := c.Param("id") return c.JSON(http.StatusOK, map[string]string{"message": "User ID: " + id}) } func adminDashboard(c echo.Context) error { return c.JSON(http.StatusOK, map[string]string{"message": "Admin dashboard"}) } // Middleware for admin routes func adminMiddleware(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { // Simulate an auth check if c.Request().Header.Get("Authorization") != "Bearer admin_token" { return c.JSON(http.StatusUnauthorized, map[string]string{"error": "Unauthorized"}) } return next(c) } }
Parse JSON to Struct in Go
Parsing JSON into a struct using json.Unmarshal is a fundamental task in Go when working with APIs or reading JSON files. The encoding/json package makes this process straightforward. Let鈥檚 say we receive the following JSON payload: { "name": "John Doe", "age": 30, "email": "johndoe@example.com" } We can parse this JSON into a struct like this: package main import ( "encoding/json" "fmt" ) type User struct { Name string `json:"name"` Age int `json:"age"` Email string `json:"email"` } func main() { jsonData := `{"name": "John Doe", "age": 30, "email": "johndoe@example.com"}` var user User err := json.Unmarshal([]byte(jsonData), &user) if err != nil { fmt.Println("Error parsing JSON:", err) return } fmt.Println("Parsed User Struct:", user) }
Request Logger Middleware in Go Echo
Middleware in Echo allows us to intercept requests before they reach handlers, making it a great place to add logging. Echo provides a built-in logging middleware (middleware.Logger()) but for more control, we can create a custom middleware: package main import ( "log" "time" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" ) // Custom logging middleware func requestLogger(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { start := time.Now() req := c.Request() log.Printf("Request: method=%s, path=%s, remote=%s", req.Method, req.URL.Path, req.RemoteAddr) err := next(c) res := c.Response() log.Printf("Response: status=%d, duration=%s", res.Status, time.Since(start)) return err } } func main() { e := echo.New() // Use Echo's default logger middleware e.Use(middleware.Logger()) // Use custom logging middleware e.Use(requestLogger) e.GET("/", func(c echo.Context) error { return c.String(200, "Hello, Echo!") }) e.Start(":8080") }
How to download all files from an S3 bucket
How to upload files to S3 using PHP SDK
How to activate a virtual environment via Bash
Create a file named anything.sh and make it executable Paste following code in file Run ./path-to-file.sh cd path/to/env/dir && source bin/activate
How to Import All CSV Files in Directory in MySQL via Bash
Create a file import.sh and make it executable Paste following code in file mysqluser='root' mysqlpass='password' mysqldb='database_name' tablename='mysql_table_name' DIRECTORY='input_directory' for csv in $DIRECTORY/*.csv; do echo "Loading $csv" mysql -u $mysqluser --password=$mysqlpass -D $mysqldb -e "LOAD DATA INFILE '$csv' IGNORE INTO TABLE $tablename FIELDS TERMINATED BY '\t' ENCLOSED BY '\"' LINES TERMINATED BY '\n' IGNORE 1 LINES;" done
How to quickly login to MySQL using Bash
I know this method isn鈥檛 the most secure way. But when I鈥檓 working on personal projects, it gets annoying having to enter credentials every time. Hence, I put together this little script to quickly log me in. I create file mysql.sh with following contents mysql -u username --password='password_here'
How to run a script if it is not already running in Linux
Let鈥檚 say you have a script called crawl.py and you never want two instances of it running at the same time. The following script can do the job RUNNING="$(ps aux|grep crawl|grep -v grep|wc -l)" if [ $RUNNING -eq 0 ] then python crawl.py else echo "Already running : skipping"; fi
How to ZIP all files in directory and send to another server
First install zip if not already install Ubuntu apt-get install zip Centos yum install zip Then create a file.sh and paste following code OUTFILE=outputfile.zip INPUTDIR=inputdir zip -R $OUTFILE $INPUTDIR scp $OUTFILE usrename@outserver:/path/of/ $OUTFILE -i key.pem
How to setup token API auth with Sanctum in Laravel
Read about Laravel Sanctum Create your laravel project composer create-project --prefer-dist laravel/laravel my-laravel-blog-api Move into project directory and then install Sanctum composer require laravel/sanctum Now let鈥檚 publish migrations and configuration files php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider" Run database migrations php artisan migrate Make sure your User model looks like this use Laravel\Sanctum\HasApiTokens; class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; } Make an authentication / user controller. Let鈥檚 use AuthenticationController for this php artisan make:controller AuthenticationController Then add following code in this controller se Illuminate\Support\Facades\Hash; public function register(Request $request) { $validatedData = $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:8', ]); $user = User::create([ 'name' => $validatedData['name'], 'email' => $validatedData['email'], 'password' => Hash::make($validatedData['password']), ]); $token = $user->createToken('auth_token')->plainTextToken; return response()->json([ 'access_token' => $token, 'token_type' => 'Bearer', ]); } First, we validate the incoming request to make sure all required variables are present. Then we persist the supplied details into the database. Once a user has been created, we create a new personal access token for them using the createToken() method and give the token a name of auth_token. Because createToken() will return an instance of Laravel\Sanctum\NewAccessToken, we call the plainTextTokenproperty on the instance to access the plain-text value of the token. Finally, we return a JSON response containing the generated token as well as the type of the token. Then add login method to your controller. It should look like this use App\Models\User; use Illuminate\Support\Facades\Auth; public function login(Request $request) { if (!Auth::attempt($request->only('email', 'password'))) { return response()->json([ 'message' => 'Invalid login details' ], 401); } $user = User::where('email', $request['email'])->firstOrFail(); $token = $user->createToken('auth_token')->plainTextToken; return response()->json([ 'access_token' => $token, 'token_type' => 'Bearer', ]); } Add following two routes to allow registrations and login Route::post('/register', [AuthController::class, 'register']); Route::post('/login', [AuthController::class, 'login']);
How to test Registration and Login in Laravel
I often work with Laravel APIs that require user registration and authentication. Of course, there is no stability in building applications without unit tests. Hence, I create following tests to ensure registration and login functions are working as expected. TestRegister.php Run php artisan make:test TestRegister Go to tests\Feature and open TestRegister.php Use following test to make sure user registrations are working. Of course, this is a minimal example. But this should give you a good idea of how you can get started. public function testsRegistration() { $payload = [ 'name' => 'Jenny', 'email' => 'jenny@test.com', 'password' => 'password', 'level' => '5', ]; $this->json('post', '/api/register', $payload) ->assertStatus(201) ->assertJsonStructure([ 'data' => [ 'access_token', 'token_type', ], ]);; } You鈥檒l need to ajdust $payload variables according to what your API鈥檚 register endpoint expects. You鈥檒l also need to adjust assertJsonStructure values based on what you are sending back as response. ...
Laravel - manually handle HTTP exceptions
Laravel automatically handles HTTP exceptions and throws errors / redirects as it sees fit. Sometimes, this isn鈥檛 an ideal behaviour. I was building an API and wanted to display custom messages for missing routes, forbidden and other errors. This can be done like this Open app\Exceptions\Handler.php If you want to handle missing models, paste following snippet in render method if ($exception instanceof ModelNotFoundException) { return response()->json([ 'error' => 'Model not found' ], 404); } If you鈥檇 like to handle other HTTP exceptions, paste the following snippet instead if ($this->isHttpException($exception)) { switch ($exception->getStatusCode()) { // not authorized case '403': return \Response::json([ 'error' => 'You are not allowed to access this' ], 403); break; // not found case '404': return \Response::json([ 'error' => 'Resource not found' ], 404); break; // internal error case '500': return \Response::json([ 'error' => 'Something went terribly wrong' ], 500); break; default: return $this->renderHttpException($exception); break; } }
How to create a user by default in Laravel
Sure, we can user Laravel鈥檚 database seeding and $faker to create any number of fake users. Personally, I don鈥檛 like to waste time fetching a new random user and their email address to continue my testing. I like have the same user created each time database is seeded. I do it like this. Run below command to create a new seeder in database/seeds directory. php artisan make:seeder UserSeeder In run method of UserSeeder.php paste following code $user = User::create([ 'name' => 'Saqib', 'email' => 'saqib@saqib.com', 'password' => Hash::make('password'), 'level' => 1 ]); Finally, add below line in run method in seeds\DatabaseSeeder.php $this->call(UserSeeder::class); ...
Ubtunu 20 Post Installation Checklist
Run an update first apt-get update Install necessary dev tools apt-get install -y zip unzip wget curl youtube-dl git subversion dconf-editor build-essential Install Sublime Text apt-get update sudo apt install -y dirmngr gnupg apt-transport-https ca-certificates software-properties-common curl -fsSL https://download.sublimetext.com/sublimehq-pub.gpg | sudo apt-key add - sudo add-apt-repository "deb https://download.sublimetext.com/ apt/stable/" sudo apt install -y sublime-text Install Google chrome apt-get update wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb sudo dpkg -i google-chrome-stable_current_amd64.deb Install Apache, MySQL, PHP, PHPMyAdmin Apache and MySQL apt-get update sudo apt install -y apache2 mysql-server sudo mysql_secure_installation PHP, PHPMyAdmin and some extensions ...
How to create and use Seeders in Laravel
Create a seeder php artisan make:seeder seederName This creates a file seederName in database/seeds You can use a model or default database class. I鈥檒l show you both examples To use an existing model, try this approach // assumes you've already added "use App\User" and "use Illuminate\Support\Facades\Hash;" at top of your file $user = User::create([ 'name' => 'Saqib', 'email' => 'saqib@saqib.com', 'password' => Hash::make('password'), 'level' => 1 ]); If you don鈥檛 have a model and want to run database inserts, try something like this DB::table('users')->insert([ 'name' => 'Jon Snow', 'email' => 'saqib@test.com', 'password' => Hash::make('password') ]); Run php artisan db:seed or php artisan migrate:fresh --seed to run seeders
The common Laravel template structure
First, create a file that defines the structure of your page layout.blade.php @include('includes.header') @yield('content') @include('includes.footer') Then create files that yield content index.blade.php @extends('common_template') @section('content') {{$data['title']}} @endsection
How to change windows wallpaper using Python3
Following code can be used for changing windows wallpaper import ctypes ctypes.windll.user32.SystemParametersInfoW(20, 0, image , 0)
Python - search questions using wolframalpha
import json, requests def search(keyword): keyword = keyword.replace(' ', '+') data = requests.get('https://api.wolframalpha.com/v2/query?input=' + keyword + '&format=plaintext&output=json&appid=api_id_here') readable = data.json() results = readable['queryresult'] if results['success'] == True: for pod in results['pods']: if pod['title'] == 'Result': try: value = pod['subpods'][0]['plaintext'] return value except Exception as e: value = '' raise e else: print('Something went wrong. Below is full data') print(readable)
Python + Scrapy: find element with text
response.xpath("//*[contains(text(), 'txt goes here')]").getall()
How to update a request URL in Scrapy
Often times you might want to be able to manipulate every outgoing request. You don鈥檛 have to modify all points in your scrapper where you鈥檙e making requests. You can modify your middleware. Open middlewares.py in your project and paste following code in process_request method original_url = request.url new_url = 'modified_url_here' request = request.replace(url=new_url)
Sublime Cheatsheet
Go to file Ctrl + P Toggle Sidebar Ctrl + K B Select line Ctrl + L Select word Ctrl + D Select content into brackets Ctrl + Shift + M Insert line before Ctrl + Shift + Enter Insert line after Ctrl + Enter Delete line Ctrl + Shift + K Duplicate lines Ctrl + Shift + D Join lines Ctrl + Shift + J Jump to matching bracket Ctrl + M ...
Laravel - create a user by default
Sure, we can user Laravel鈥檚 database seeding and $faker to create any number of fake users. Personally, I don鈥檛 like to waste time fetching a new random user and their email address to continue my testing. I like have the same user created each time database is seeded. I do it like this. Run below command to create a new seeder in database/seeds directory. php artisan make:seeder UserSeeder In run method of UserSeeder.php paste following code $user = User::create([ 'name' => 'Saqib', 'email' => 'saqib@saqib.com', 'password' => Hash::make('password'), 'level' => 1 ]); Finally, add below line in run method in seeds\DatabaseSeeder.php $this->call(UserSeeder::class); ...
Git Cheatsheet
Git Cheatsheet Get remote URL git remote -v Set remote URL git remote set-url origin git@bitbucket.org:user/repo.git Update remote branches list git remote update origin --prune Delete local branch git branch -d branchname Delete branch locally and remote git push origin --delete fix/authentication Create branch from another git checkout -b newbranch sourcebranch Soft reset (remove last commit) git reset --soft HEAD~1 Remove all local branches already merged into master (including dev) git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d
Python - read txt file separated by line as list
In a web crawling project of mine I had to read proxies from a txt file. Each proxy was on a new line. I used following code to read them as list. proxies = [line.rstrip('\n') for line in open(directory + '/proxies_v2.txt')] Additionally, I shuffle them to make sure their order is random. random.shuffle(proxies)
MySQL Cheatsheet
copy a table with schema, indexes and data First, copy the table with indexes CREATE TABLE new_name LIKE table_to_copy; Then copy the data by running INSERT INTO new_name SELECT * FROM table_to_copy; create BTREE Indexes CREATE INDEX index_name ON table_name (column1, column2, ...); create FULLTEXT indexes ALTER TABLE `TableName` ADD FULLTEXT INDEX `IndexName` (`ColumnName`); create new user and give all privilages CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON * . * TO 'user'@'localhost'; create or drop multiple indexes in same query Create multiple indexes ...
How to modify Laravel 'HOME' redirection path
When a user logs in, Laravel redirects it to path stored in HOME constant by default. If you want to modify this constant or add constants of your own, you can do it like this. Open app\Providers\RouteServiceProvider.php Search public const HOME to update HOME constant You can add your own just like that
Laravel - common template structure
First, create a file that defines the structure of your page layout.blade.php @include('includes.header') @yield('content') @include('includes.footer') Then create files that yield content index.blade.php @extends('common_template') @section('content') {{$data['title']}} @endsection
How to use proxies with Requests in Python
import requests proxy = 'proxy:goes:here' proxyDict = {"http" : proxy, "https" : proxy} response = requests.get('https://www.url.com', proxies=proxyDict) You can send the POST requests using a similar format. Headers can be added to the request using headers={}