Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions base/openapi/api.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"openapi": "3.1.0", "info": {"title": "base", "version": "0.0.0"}, "paths": {"/version": {"get": {"summary": "Version", "operationId": "version_version_get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}}}}}}
14 changes: 1 addition & 13 deletions base/service.codefly.yaml
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
kind: service
name: base
application: base
namespace: default
module: base
version: 0.0.0
plugin:
kind: runtime::service
name: python-fastapi
version: latest
publisher: codefly.ai
endpoints:
- name: grpc
api: grpc
- name: rest
public: true
api: rest
spec:
create-rest-endpoint: true
debug: false
watch: true
with-debug-symbols: false
3 changes: 0 additions & 3 deletions base/service.generation.codefly.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
base:
name: base
domain: github.com/codefly-dev/python-fastapi/base
ignores:
- service.codefly.yaml
- service.generation.codefly.yaml
- __pycache__
- poetry.lock
4 changes: 2 additions & 2 deletions base/src/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import codefly.codefly as codefly
import codefly_sdk.codefly as codefly

codefly.init()

Expand All @@ -21,4 +21,4 @@

@app.get("/version")
async def version():
return {"version": codefly.get_service().version}
return {"version": codefly.get_version()}
10 changes: 4 additions & 6 deletions base/src/openapi.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import json
from main import app
import codefly.codefly as codefly

import codefly_sdk.codefly as codefly
from fastapi.openapi.utils import get_openapi

if __name__ == "__main__":
service = codefly.get_service()
openapi_schema = get_openapi(
title=service.name,
version=service.version,
title=codefly.get_service(),
version=codefly.get_version(),
routes=app.routes,
)
app.openapi_schema = openapi_schema
openapi = app.openapi()
with open("../openapi/api.swagger.json", "w") as f:
with open("../openapi/api.json", "w") as f:
f.write(json.dumps(openapi))
761 changes: 570 additions & 191 deletions base/src/poetry.lock

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions base/src/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ authors = ["Your Name <you@example.com>"]
python = "^3.10"
fastapi = "^0.109.0"
uvicorn = "^0.25.0"
codefly-sdk = "^0.0.10"
codefly-sdk = "^0.0.12"

[tool.poetry.dev-dependencies]
[tool.poetry.group.dev.dependencies]
pytest = "^8.2.0"
httpx = "^0.27.0"
pytest-asyncio = "^0.23.6"
codefly-cli = "^0.0.1"

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down
17 changes: 17 additions & 0 deletions base/src/tests/test_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import sys, os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

from httpx import AsyncClient, ASGITransport
import pytest
from main import app
import codefly_sdk.codefly as codefly


@pytest.mark.asyncio
async def test_read_root():
codefly.init("..")
endpoint = codefly.endpoint(api="rest")
async with AsyncClient(transport=ASGITransport(app=app), base_url=endpoint.address) as ac:
response = await ac.get("/version")
assert response.status_code == 200
assert response.json() == {"version": "0.0.0"}
108 changes: 61 additions & 47 deletions builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import (
"github.com/codefly-dev/core/agents/communicate"
dockerhelpers "github.com/codefly-dev/core/agents/helpers/docker"
"github.com/codefly-dev/core/agents/services"
"github.com/codefly-dev/core/configurations"
"github.com/codefly-dev/core/configurations/standards"
basev0 "github.com/codefly-dev/core/generated/go/base/v0"
agentv0 "github.com/codefly-dev/core/generated/go/services/agent/v0"
builderv0 "github.com/codefly-dev/core/generated/go/services/builder/v0"
"github.com/codefly-dev/core/resources"
"github.com/codefly-dev/core/shared"
"github.com/codefly-dev/core/standards"
"github.com/codefly-dev/core/templates"
"github.com/codefly-dev/core/wool"
)
Expand All @@ -28,7 +28,7 @@ func NewBuilder() *Builder {
func (s *Builder) Load(ctx context.Context, req *builderv0.LoadRequest) (*builderv0.LoadResponse, error) {
defer s.Wool.Catch()

err := s.Base.Builder.Load(ctx, req.Identity, s.Settings)
err := s.Builder.Load(ctx, req.Identity, s.Settings)
if err != nil {
return nil, err
}
Expand All @@ -37,18 +37,20 @@ func (s *Builder) Load(ctx context.Context, req *builderv0.LoadRequest) (*builde

s.sourceLocation = s.Local("src")

// communication on CreateResponse
err = s.Communication.Register(ctx, communicate.New[builderv0.CreateRequest](createCommunicate()))
if err != nil {
return s.Builder.LoadError(err)
}

s.Builder.GettingStarted, err = templates.ApplyTemplateFrom(ctx, shared.Embed(factoryFS), "templates/factory/GETTING_STARTED.md", s.Information)
if err != nil {
return s.Builder.LoadError(err)
}
if req.CreationMode != nil {
s.Builder.CreationMode = req.CreationMode
s.Builder.GettingStarted, err = templates.ApplyTemplateFrom(ctx, shared.Embed(factoryFS), "templates/factory/GETTING_STARTED.md", s.Information)
if err != nil {
return s.Builder.LoadError(err)
}

if req.AtCreate {
if req.CreationMode.Communicate {
// communication on CreateResponse
err = s.Communication.Register(ctx, communicate.New[builderv0.CreateRequest](s.createCommunicate()))
if err != nil {
return s.Builder.LoadError(err)
}
}
return s.Builder.LoadResponse()
}

Expand All @@ -57,7 +59,7 @@ func (s *Builder) Load(ctx context.Context, req *builderv0.LoadRequest) (*builde
return s.Builder.LoadError(err)
}

s.restEndpoint, err = configurations.FindRestEndpoint(ctx, s.Endpoints)
s.RestEndpoint, err = resources.FindRestEndpoint(ctx, s.Endpoints)
if err != nil {
return s.Builder.LoadError(err)
}
Expand Down Expand Up @@ -120,9 +122,8 @@ func (s *Builder) Build(ctx context.Context, req *builderv0.BuildRequest) (*buil
ctx = s.Wool.Inject(ctx)

docker := DockerTemplating{
Builder: runtimeImage.FullName(),
Components: requirements.All(),
RuntimePackages: s.Settings.RuntimePackages,
Builder: runtimeImage.FullName(),
Components: requirements.All(),
}

err = shared.DeleteFile(ctx, s.Local("builder/Dockerfile"))
Expand Down Expand Up @@ -201,7 +202,7 @@ func (s *Builder) Deploy(ctx context.Context, req *builderv0.DeploymentRequest)
Parameters: Parameters{LoadBalancer{}},
}
if req.Deployment.LoadBalancer {
inst, err := configurations.FindNetworkInstanceInNetworkMappings(ctx, req.NetworkMappings, s.restEndpoint, basev0.NetworkScope_Public)
inst, err := resources.FindNetworkInstanceInNetworkMappings(ctx, req.NetworkMappings, s.RestEndpoint, resources.NewPublicNetworkAccess())
if err != nil {
return s.Builder.DeployError(err)
}
Expand All @@ -214,19 +215,19 @@ func (s *Builder) Deploy(ctx context.Context, req *builderv0.DeploymentRequest)
return s.Builder.DeployResponse()
}

const Watch = "with-hot-reload"
const PublicEndpoint = "public-endpoint"
func (s *Builder) Options() []*agentv0.Question {
return []*agentv0.Question{communicate.NewConfirm(&agentv0.Message{Name: PublicEndpoint, Message: "Expose API as public", Description: "is that directly accessible from the internet?"}, true),
communicate.NewConfirm(&agentv0.Message{Name: HotReload, Message: "Code hot-reload (Recommended)?", Description: "codefly can restart your service when code changes are detected 🔎"}, true),
}
}

func createCommunicate() *communicate.Sequence {
return communicate.NewSequence(
communicate.NewConfirm(&agentv0.Message{Name: PublicEndpoint, Message: "Expose API as public", Description: "is that directly accessible from the internet?"}, true),
communicate.NewConfirm(&agentv0.Message{Name: Watch, Message: "Code hot-reload (Recommended)?", Description: "codefly can restart your service when code changes are detected 🔎"}, true),
)
func (s *Builder) createCommunicate() *communicate.Sequence {
return communicate.NewSequence(s.Options()...)
}

type CreateConfiguration struct {
*services.Information
Image *configurations.DockerImage
Image *resources.DockerImage
Envs []string
}

Expand All @@ -235,50 +236,63 @@ func (s *Builder) Create(ctx context.Context, req *builderv0.CreateRequest) (*bu

ctx = s.Wool.Inject(ctx)

session, err := s.Communication.Done(ctx, communicate.Channel[builderv0.CreateRequest]())
if err != nil {
return s.Builder.CreateError(err)
}
if s.Builder.CreationMode.Communicate {
session, err := s.Communication.Done(ctx, communicate.Channel[builderv0.CreateRequest]())
if err != nil {
return s.Builder.CreateError(err)
}

s.Settings.Watch, err = session.Confirm(Watch)
if err != nil {
return s.Builder.CreateError(err)
s.Settings.HotReload, err = session.Confirm(HotReload)
if err != nil {
return s.Builder.CreateError(err)
}
s.Settings.PublicEndpoint, err = session.Confirm(PublicEndpoint)
if err != nil {
return s.Builder.CreateError(err)
}
} else {
var err error
s.Settings.HotReload, err = communicate.GetDefaultConfirm(s.Options(), HotReload)
if err != nil {
return s.Builder.CreateError(err)
}
s.Settings.PublicEndpoint, err = communicate.GetDefaultConfirm(s.Options(), PublicEndpoint)
if err != nil {
return s.Builder.CreateError(err)
}
}

create := CreateConfiguration{
Information: s.Information,
Envs: []string{},
}
withPublicEndpoint, err := session.Confirm(PublicEndpoint)

err := s.Templates(ctx, create, services.WithFactory(factoryFS))
if err != nil {
return s.Builder.CreateError(err)
}
err = s.Templates(ctx, create, services.WithFactory(factoryFS))
if err != nil {
return s.Base.Builder.CreateError(err)
}

err = s.CreateEndpoints(ctx, withPublicEndpoint)
err = s.CreateEndpoints(ctx)
if err != nil {
return nil, s.Wool.Wrapf(err, "cannot create endpoints")
}

return s.Base.Builder.CreateResponse(ctx, s.Settings)
return s.Builder.CreateResponse(ctx, s.Settings)
}

func (s *Builder) CreateEndpoints(ctx context.Context, withPublicEndpoint bool) error {
func (s *Builder) CreateEndpoints(ctx context.Context) error {
openapiFile := s.Local("openapi/api.json")
var err error
endpoint := s.Base.Service.BaseEndpoint(standards.REST)
if withPublicEndpoint {
endpoint.Visibility = configurations.VisibilityPublic
if s.Settings.PublicEndpoint {
endpoint.Visibility = resources.VisibilityPublic
}
rest, err := configurations.LoadRestAPI(ctx, shared.Pointer(openapiFile))
s.restEndpoint, err = configurations.NewAPI(ctx, endpoint, configurations.ToRestAPI(rest))
rest, err := resources.LoadRestAPI(ctx, shared.Pointer(openapiFile))
s.RestEndpoint, err = resources.NewAPI(ctx, endpoint, resources.ToRestAPI(rest))
if err != nil {
return s.Wool.Wrapf(err, "cannot create openapi api")
}
s.Endpoints = []*basev0.Endpoint{s.restEndpoint}
s.Endpoints = []*basev0.Endpoint{s.RestEndpoint}
return nil
}

Expand Down
50 changes: 23 additions & 27 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,26 @@ module github.com/codefly-dev/service-python-fastapi
go 1.22.0

require (
github.com/codefly-dev/core v0.1.88
github.com/codefly-dev/core v0.1.90
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-plugin v1.6.0
github.com/stretchr/testify v1.9.0
google.golang.org/grpc v1.63.2
)

require (
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240401165935-b983156c5e99.1 // indirect
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.34.1-20240508200655-46a4cf4ba109.1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/bufbuild/protovalidate-go v0.6.1 // indirect
github.com/bufbuild/protovalidate-go v0.6.2 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cheggaaa/pb/v3 v3.1.5 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/docker v26.0.2+incompatible // indirect
github.com/docker/docker v26.1.2+incompatible // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dsnet/compress v0.0.1 // indirect
Expand All @@ -50,6 +49,7 @@ require (
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
github.com/hashicorp/go-plugin v1.6.1 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74 // indirect
Expand All @@ -71,35 +71,31 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/shirou/gopsutil/v3 v3.24.3 // indirect
github.com/shirou/gopsutil/v3 v3.24.4 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/stoewer/go-strcase v1.3.0 // indirect
github.com/tklauser/go-sysconf v0.3.13 // indirect
github.com/tklauser/numcpus v0.7.0 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/yoheimuta/go-protoparser/v4 v4.10.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.mongodb.org/mongo-driver v1.15.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 // indirect
go.opentelemetry.io/otel v1.25.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect
go.opentelemetry.io/otel v1.26.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 // indirect
go.opentelemetry.io/otel/metric v1.25.0 // indirect
go.opentelemetry.io/otel/sdk v1.25.0 // indirect
go.opentelemetry.io/otel/trace v1.25.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 // indirect
go.opentelemetry.io/otel/metric v1.26.0 // indirect
go.opentelemetry.io/otel/sdk v1.26.0 // indirect
go.opentelemetry.io/otel/trace v1.26.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.20.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
google.golang.org/protobuf v1.33.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240509183442-62759503f434 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading