Managing FastAPI Projects with Poetry: A Step-by-Step Guide

Image
This guide will walk you through how to use Poetry to manage dependencies and structure your project in FastAPI . It includes detailed explanations of Poetry's core concepts and commands to help prevent issues that can arise during team collaboration and deployment. 1. What is Poetry? Poetry is a dependency management and packaging tool for Python. It goes beyond simply installing libraries by allowing you to clearly declare the dependencies your project needs and ensuring that all developers on the project have the same library versions. Clarity in Dependency Management : Explicitly manage your project's basic information and required libraries through the pyproject.toml file. Reproducible Builds : By locking all dependency versions in the poetry.lock file, it fundamentally prevents "it works on my machine" problems. Integrated Development Environment : It automatically creates and manages isolated virtual environments for each project and handles mo...

Managing Shared Libraries in Microservice Architecture Using GCP Artifact Registry

GCP Artifact Registry

In a microservice architecture, it's common for multiple services to share common functionality or utility classes. To handle this effectively, I manage these shared components as a reusable library (like libs.jar) that each service can depend on. In this post, I’ll show you how I use GCP Artifact Registry to efficiently manage and distribute a shared library across microservices.

Step 1: Enable the Artifact Registry API

$ gcloud services enable artifactregistry.googleapis.com --project=[PROJECT_ID]

Step 2: Create a Maven Repository in GCP Artifact Registry

$ gcloud artifacts repositories create maven-repo \
  --repository-format=maven \
  --location=us-central1 \
  --description="Shared Maven Repo for common libraries"

$ gcloud artifacts repositories list --location=us-central1
REPOSITORY        FORMAT  LOCATION      DESCRIPTION
maven-repo        MAVEN   us-central1   Shared Maven repo

Step 3: Configure pom.xml for the Shared Library Project

In the shared library (libs) project's pom.xml, I define the following:

  • groupId: A unique identifier for my organization or project (e.g., com.example.libs)
  • artifactId: The name of the library (e.g., libs)
  • version: The library version (e.g., 1.0.1)
  • packaging: The packaging type (jar is recommended for reusable libraries)

If the packaging tag is missing or incorrect, Maven may mistakenly treat the library as pom, war, or another type — leading to problems when uploading to Artifact Registry or importing it into other projects.

<groupId>com.example.libs</groupId>
<artifactId>libs</artifactId>
<version>1.0.1</version>
<packaging>jar</packaging>

GCP Artifact Registry for Maven requires using the artifactregistry:// protocol instead of https://. Otherwise, authentication and upload may not work properly.

For snapshot versions (e.g., 0.0.1-SNAPSHOT), Maven appends a timestamp to ensure uniqueness. Release versions remain fixed.

<distributionManagement>
  <snapshotRepository>
    <id>artifact-registry</id>
    <url>artifactregistry://us-central1-maven.pkg.dev/[PROJECT_ID]/maven-repo</url>
  </snapshotRepository>
  <repository>
    <id>artifact-registry</id>
    <url>artifactregistry://us-central1-maven.pkg.dev/[PROJECT_ID]/maven-repo</url>
  </repository>
</distributionManagement>
Version Type Example Description
<releases> 1.0.0 Stable release; cannot be overwritten once uploaded
<snapshots> 0.0.1-SNAPSHOT Development version; overwritten with timestamped versions
<repositories>
  <repository>
    <id>artifact-registry</id>
    <url>artifactregistry://us-central1-maven.pkg.dev/[PROJECT_ID]/maven-repo</url>
    <releases><enabled>true</enabled></releases>
    <snapshots><enabled>true</enabled></snapshots>
  </repository>
</repositories>

Add Artifact Registry Maven Wagon Extension
To allow Maven to understand the artifactregistry://... protocol, I include the official Google Artifact Registry Maven Wagon extension.

<build>
  <extensions>
    <extension>
      <groupId>com.google.cloud.artifactregistry</groupId>
      <artifactId>artifactregistry-maven-wagon</artifactId>
      <version>2.2.5</version>
    </extension>
  </extensions>
</build>

Step 4: Configure application.yaml for the Shared Library

I disable unnecessary auto-configuration to avoid errors — especially since the shared library doesn't require a database.

spring:  
  application:  
    name: libs  
  autoconfigure:  
    exclude:  
      - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration  
      - org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration

Step 5: Maven Authentication Configuration

Using the Credential Helper

Artifact Registry requires authentication. Since the access token from gcloud auth print-access-token only lasts 1 hour, I use the credential helper provided by gcloud to handle automatic token renewal for Maven.

On Windows, the credentials are stored in:

C:\Users\[USER]\AppData\Roaming\gcloud\application_default_credentials.json

I run the following command to enable this:

$ gcloud auth application-default login

Grant Cloud Build Access

In CI/CD environments like Cloud Build, I make sure the service account has the necessary roles to access Artifact Registry.

gcloud projects add-iam-policy-binding [PROJECT_ID] \
  --member="serviceAccount:[PROJECT_NUMBER]-compute@developer.gserviceaccount.com" \
  --role="roles/artifactregistry.reader"

gcloud projects add-iam-policy-binding [PROJECT_ID] \
  --member="serviceAccount:[PROJECT_NUMBER]-compute@developer.gserviceaccount.com" \
  --role="roles/artifactregistry.writer"

Step 6: Provide a Custom settings.xml for Maven

Since Cloud Build runs on a remote server and doesn't have access to my local ~/.m2/settings.xml, I include a settings.xml file in the build context (the project's root directory) and explicitly specify it using the -s option.

<settings>
  <servers>
    <server>
      <id>artifact-registry</id>
      <username>oauth2accesstoken</username>
      <password>
        <!-- empty is fine; gcloud helper will inject the token -->
      </password>
    </server>
  </servers>
</settings>

On my local machine, Maven uses:

C:\Users\[USER]\.m2\settings.xml

Step 7: Create cloudbuild.yaml

  • I use -DskipTests to skip running tests, which speeds up the build process. This is especially useful for shared libraries that are frequently updated and published.
  • Cloud Build automatically mounts the build context (e.g., .) to /workspace inside the build container.
  • I add -B to enable batch mode, which makes the Maven output cleaner.
steps:  
  # 1. Build the JAR without running tests  
  - name: 'gcr.io/cloud-builders/mvn'  
    entrypoint: 'mvn'  
    args: ['clean', 'package', '-DskipTests']  
  
  # 2. Deploy the JAR to Artifact Registry  
  - name: 'gcr.io/cloud-builders/mvn'  
    args: ['deploy',
           '-B',
           '-s', '/workspace/settings.xml']

Step 8: Modify pom.xml of Each Services

In this step, I configure each microservice (a-service, b-service, etc.) to use the shared library.

1. Add the shared library dependency

<dependency>
  <groupId>com.example.libs</groupId>
  <artifactId>libs</artifactId>
  <version>1.0.1</version>
</dependency>
  • The values must exactly match those used in the libs project.

2. Add the Artifact Registry Maven extension

<extension>  
  <groupId>com.google.cloud.artifactregistry</groupId>  
  <artifactId>artifactregistry-maven-wagon</artifactId>  
  <version>2.2.5</version>  
</extension>
  • This is required so Maven can resolve artifactregistry:// URLs.

3. Add the repository information

<repositories>
  <repository>
    <id>artifact-registry</id>
    <url>artifactregistry://us-central1-maven.pkg.dev/[PROJECT_ID]/maven-repo</url>
    <releases><enabled>true</enabled></releases>
    <snapshots><enabled>true</enabled></snapshots>
  </repository>
</repositories>
  • Replace [PROJECT_ID] with your actual GCP project ID.
  • Ensure the region (us-central1) matches where your Artifact Registry is located.
  • This tells Maven where to look for the shared library.

Step 9: Add settings.xml in the service's root directory

To enable Maven to authenticate with GCP Artifact Registry during the build the services, the following command to configure authentication for gcloud:

$ gcloud auth application-default login

Next, I place a settings.xml file in the root directory of the service. This file provides the necessary credentials using oauth2accesstoken, allowing Maven to access the GCP Artifact Registry and retrieve the shared library during the build.

<settings>
    <servers>
        <server>
            <id>artifact-registry</id>
            <username>oauth2accesstoken</username>
            <password>
	            <!-- empty is fine; gcloud helper will inject the token -->
	        </password>
        </server>
    </servers>
</settings>

Then, I reference this file explicitly in the cloudbuild.yaml using the -s flag:

steps:  
  # 1. Java Build
  - name: 'gcr.io/cloud-builders/mvn'  
    args: ['clean', 'package',
           '-DskipTests',
           '-B',
           '-s', '/workspace/settings.xml']

Comments

Popular posts from this blog

Resolving Key Exchange Failure When Connecting with SecureCRT to OpenSSH

SecureCRT] How to Back Up and Restore SecureCRT Settings on Windows

How to Set Up Vaultwarden (Bitwarden) on Synology NAS (Best Free Alternative to LastPass)