apigen_copier is a Python package that generates backend project scaffolds from API contracts.
It is designed to be used as a dependency inside other Python projects that want to automate service creation from OpenAPI or AsyncAPI input. The generator reads a structured contract, applies Copier + Jinja templates, and creates a project skeleton that can later be extended by hand.
This repository is useful when you want to:
- generate a Python service from an API-first contract
- standardize the structure of generated projects across teams
- bootstrap REST or event-driven services with less manual setup
- regenerate a project without losing preserved custom code blocks
The generated output is focused on a layered Python backend structure, including domain models, infrastructure code, routes, services, repositories, mappers, and supporting files.
Use generate_project(...) when your input is an OpenAPI YAML or JSON file.
The package parses:
x-apigen-projectfor project-level configurationcomponents.x-apigen-modelsfor domain/entity definitionspathsplusx-apigen-bindingfor route-to-model bindingcomponents.schemasfor request and response shapes
Use generate_async_project(...) when your input is already parsed into a Python dict compatible with AsyncAPIProjectSchema.
This flow is intended for event-driven services and supports concepts such as:
- brokers and servers
- channels
- operations
- message payload schemas
- entity definitions used during generation
pip install "git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.git"git+https://gitlab.com/cloudappi/clo-innova/opendataspace/ods-data-generator-examples.gitpip install .The package exposes these main entry points:
from apigen_copier import (
generate_project,
generate_from_schema,
generate_async_project,
generate_from_async_schema,
)The most common integration is:
- Add
apigen_copieras a dependency - Store an API contract in your project
- Call the generator from a Python script, command, or build step
- Commit or process the generated output
Example:
from apigen_copier import generate_project
generate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)If you want to regenerate an existing generated project and preserve custom code blocks:
from apigen_copier import generate_project
generate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
existing_project_dir="generated/pet-service",
)For generate_project(...), the input must be a YAML or JSON file.
If the file contains openapi or swagger, the package treats it as an OpenAPI specification and parses it automatically.
openapi: 3.0.0
info:
title: Pet API
version: 1.0.0
x-apigen-project:
name: Pet Service
version: 1.0.0
description: Service generated from OpenAPI
data-driver: postgresql
prefix: /api/v1
paths:
/pets:
x-apigen-binding:
model: Pet
get:
operationId: listPets
responses:
"200":
description: OK
post:
operationId: createPet
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/PetCreate"
responses:
"201":
description: Created
/pets/{id}:
x-apigen-binding:
model: Pet
get:
operationId: getPetById
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/PetGet"
components:
x-apigen-models:
Pet:
relational-persistence:
table: pets
attributes:
- name: id
type: String
relational-persistence:
primary-key: true
autogenerated: true
- name: name
type: String
- name: status
type: String
schemas:
PetGet:
x-apigen-mapping:
model: Pet
method: get
type: object
properties:
id:
type: string
name:
type: string
status:
type: string
PetCreate:
x-apigen-mapping:
model: Pet
method: post
type: object
properties:
name:
type: string
status:
type: stringx-apigen-projectdefines the generated project metadatacomponents.x-apigen-modelsdefines the domain models used by the generator- each model should define a primary key
- only operations with
x-apigen-bindingare turned into generated routers components.schemasis used to infer request and response modelsdata-drivercurrently accepts values such aspostgresql,mysql,oracle,sqlite,mssql, ands3
For generate_async_project(...), the input is a Python dict, not a raw file path.
At minimum, the dictionary should contain:
projectserverschannelsoperationsentitiescomponents
Example:
from apigen_copier import generate_async_project
parsed_data = {
"project": {
"name": "order-events-service",
"version": "1.0.0",
"description": "Async generated service",
"data-driver": "postgresql",
},
"servers": {
"kafka-dev": {
"host": "localhost:9092",
"protocol": "kafka",
"security": [],
}
},
"channels": {
"orderEvents": {
"address": "orders.events",
"parameters": {},
"messages": {},
}
},
"operations": {
"onOrderCreated": {
"action": "receive",
"channel": {
"address": "orders.events",
"parameters": {},
"messages": {},
},
"bindings": {"kafka": {"groupId": "order-service-group"}},
"reply": None,
"messages": [],
}
},
"entities": {
"Order": {
"table": "orders",
"attributes": [
{
"name": "id",
"type": "String",
"relational-persistence": {
"primary-key": True,
"autogenerated": False,
},
}
],
}
},
"components": {
"schemas": {}
},
}
generate_async_project(
parsed_data=parsed_data,
output_dir="generated/order-events-service",
)Depending on the input and template, the package can generate files such as:
- project scaffolding
- domain models
- route modules
- repositories
- services
- mappers
- broker configuration
- DTOs and response models
One of the important features of this package is regeneration support.
When existing_project_dir is provided, the generator can:
- extract preserved custom code blocks from the previous project
- inject them into the regenerated project
- copy an existing
UserCode/folder into the new output
This makes the package suitable not only for one-time scaffolding, but also for iterative generation workflows.
In a consuming repository, a common setup is:
my-python-project/
├── specs/
│ └── petstore.yaml
├── scripts/
│ └── generate_service.py
├── generated/
│ └── pet-service/
└── pyproject.toml or requirements.txt
Example generator script:
from apigen_copier import generate_project
def main() -> None:
generate_project(
input_path="specs/petstore.yaml",
output_dir="generated/pet-service",
)
if __name__ == "__main__":
main()Then run:
python scripts/generate_service.pyapigen_copier is a reusable Python dependency for teams that want to generate backend projects from API contracts instead of writing the initial boilerplate by hand. Its main value is that it turns structured API input into a maintainable project skeleton and supports safe regeneration when the contract evolves.