Question: Trying to publish a Poetry package to AWS CodeArtifact. It supports pip which should indicate that it supports poetry as well since poetry can upload to PyPi servers. I've configured the domain like so: export CODEARTIFACT_AUTH_TOKEN=`aws codeartifact get-authorization-token --domain XXXX --domain-owner XXXXXXXXXXXX --query authorizationToken --output text` poetry config repositories.the_aws_repo https://aws:$CODEARTIFACT_AUTH_TOKEN@XXXX-XXXXXXXXXXXX.d.codeartifact.eu-central-1.amazonaws.com/pypi/XXXX/simple/ poetry config pypi-token.the_aws_repo $CODEARTIFACT_AUTH_TOKEN  But I'm getting 404 when trying to publish the package: ❯ poetry publish --repository the_aws_repo -vvv No suitable keyring backend found No suitable keyring backends were found Using a plaintext file to store and retrieve credentials Publishing xxx (0.1.5) to the_aws_repo - Uploading xxx-0.1.5-py3-none-any.whl 100% Stack trace: 7 ~/.poetry/lib/poetry/_vendor/py3.8/clikit/console_application.py:131 in run 129│ parsed_args = resolved_command.args 130│ → 131│ status_code = command.handle(parsed_args, io) 132│ except KeyboardInterrupt: 133│ status_code = 1 6 ~/.poetry/lib/poetry/_vendor/py3.8/clikit/api/command/command.py:120 in handle 118│ def handle(self, args, io): # type: (Args, IO) -> int 119│ try: → 120│ status_code = self._do_handle(args, io) 121│ except KeyboardInterrupt: 122│ if io.is_debug(): 5 ~/.poetry/lib/poetry/_vendor/py3.8/clikit/api/command/command.py:171 in _do_handle 169│ handler_method = self._config.handler_method 170│ → 171│ return getattr(handler, handler_method)(args, io, self) 172│ 173│ def __repr__(self): # type: () -> str 4 ~/.poetry/lib/poetry/_vendor/py3.8/cleo/commands/command.py:92 in wrap_handle 90│ self._command = command 91│ → 92│ return self.handle() 93│ 94│ def handle(self): # type: () -> Optional[int] 3 ~/.poetry/lib/poetry/console/commands/publish.py:77 in handle 75│ ) 76│ → 77│ publisher.publish( 78│ self.option("repository"), 79│ self.option("username"), 2 ~/.poetry/lib/poetry/publishing/publisher.py:93 in publish 91│ ) 92│ → 93│ self._uploader.upload( 94│ url, 95│ cert=cert or get_cert(self._poetry.config, repository_name), 1 ~/.poetry/lib/poetry/publishing/uploader.py:119 in upload 117│ 118│ try: → 119│ self._upload(session, url, dry_run) 120│ finally: 121│ session.close() UploadError HTTP Error 404: Not Found at ~/.poetry/lib/poetry/publishing/uploader.py:216 in _upload 212│ self._register(session, url) 213│ except HTTPError as e: 214│ raise UploadError(e) 215│ → 216│ raise UploadError(e) 217│ 218│ def _do_upload( 219│ self, session, url, dry_run=False 220│ ): # type: (requests.Session, str, Optional[bool]) -> None  My AWS IAM user has permission to do this since I gave it the relevant permissions in the repo. { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::XXXXXXXXXXXX:user/ShayN" }, "Action": [ "codeartifact:AssociateExternalConnection", "codeartifact:CopyPackageVersions", "codeartifact:DeletePackageVersions", "codeartifact:DeleteRepository", "codeartifact:DeleteRepositoryPermissionsPolicy", "codeartifact:DescribePackageVersion", "codeartifact:DescribeRepository", "codeartifact:DisassociateExternalConnection", "codeartifact:DisposePackageVersions", "codeartifact:GetPackageVersionReadme", "codeartifact:GetRepositoryEndpoint", "codeartifact:ListPackageVersionAssets", "codeartifact:ListPackageVersionDependencies", "codeartifact:ListPackageVersions", "codeartifact:ListPackages", "codeartifact:PublishPackageVersion", "codeartifact:PutPackageMetadata", "codeartifact:PutRepositoryPermissionsPolicy", "codeartifact:ReadFromRepository", "codeartifact:UpdatePackageVersionsStatus", "codeartifact:UpdateRepository" ], "Resource": "*" } ] }  What am I missing?

Answer: The problem is the /simple/ at the end of the repo url. This part should only be added when pulling from that repo, not when publishing to it. If you look closely to the documentation of AWS CodeArtifact on how to publish with twine, you'll see that it's also not there. This works: # This will give the repo url without the /simple/ part # Example: https://<my-domain>-<domain-owner-id>.d.codeartifact.<region>.amazonaws.com/pypi/<my-repo>/ # Note the lack of the "aws:auth-token@" part export CODEARTIFACT_REPOSITORY_URL=`aws codeartifact get-repository-endpoint --domain my-domain --domain-owner domain-owner-id --repository my-repo --format pypi --query repositoryEndpoint --output text` # This will give the token to access the repo export CODEARTIFACT_AUTH_TOKEN=`aws codeartifact get-authorization-token --domain my-domain --domain-owner domain-owner-id --query authorizationToken --output text` # This specifies the user who accesses the repo export CODEARTIFACT_USER=aws # Now use all of these when configuring the repo in poetry poetry config repositories.<my-repo-name-for-poetry> $CODEARTIFACT_REPOSITORY_URL poetry config http-basic.<my-repo-name-for-poetry> $CODEARTIFACT_USER $CODEARTIFACT_AUTH_TOKEN  Note that the authentication token will expire when your AWS login session ends. Hence, you'll have to set the http-basic.<my-repo-name-for-poetry> with the new token every time it expires. FYI, I had the same problem and it took me hours to figure this out. But in the end, more carefully reading the documentation should have helped me.